public static void lua_callk(lua_State L, int nargs, int nresults, int ctx, lua_CFunction k) { StkId func; lua_lock(L); api_check(L, k == null || isLua(L.ci) == 0, "cannot use continuations inside hooks"); api_checknelems(L, nargs + 1); api_check(L, L.status == LUA_OK, "cannot do calls on non-normal thread"); checkresults(L, nargs, nresults); func = L.top - (nargs + 1); if (k != null && L.nny == 0) /* need to prepare continuation? */ { L.ci.u.c.k = k; /* save continuation */ L.ci.u.c.ctx = ctx; /* save context */ luaD_call(L, func, nresults, 1); /* do the call */ } else /* no continuation or no yieldable */ { luaD_call(L, func, nresults, 0); /* just do the call */ } adjustresults(L, nresults); lua_unlock(L); }
public static int lua_yieldk (lua_State L, int nresults, int ctx, lua_CFunction k) { CallInfo ci = L.ci; luai_userstateyield(L, nresults); lua_lock(L); api_checknelems(L, nresults); if (L.nny > 0) { if (L != G(L).mainthread) luaG_runerror(L, "attempt to yield across a C-call boundary"); else luaG_runerror(L, "attempt to yield from outside a coroutine"); } L.status = LUA_YIELD; ci.extra = savestack(L, ci.func); /* save current 'func' */ if (isLua(ci) != 0) { /* inside a hook? */ api_check(L, k == null, "hooks cannot continue after yielding"); } else { if ((ci.u.c.k = k) != null) /* is there a continuation? */ ci.u.c.ctx = ctx; /* save context */ ci.func = L.top - nresults - 1; /* protect stack below results */ luaD_throw(L, LUA_YIELD); } lua_assert(ci.callstatus & CIST_HOOKED); /* must be inside a hook */ lua_unlock(L); return 0; /* return to 'luaD_hook' */ }
public static void lua_pushcclosure(lua_State L, lua_CFunction fn, int n) { lua_lock(L); if (n == 0) { setfvalue(L.top, fn); } else { Closure cl; api_checknelems(L, n); api_check(L, n <= MAXUPVAL, "upvalue index too large"); luaC_checkGC(L); cl = luaF_newCclosure(L, n); cl.c.f = fn; L.top -= n; while (n-- != 0) { setobj2n(L, cl.c.upvalue[n], L.top + n); } setclCvalue(L, L.top, cl); } api_incr_top(L); lua_unlock(L); }
public static void lua_pushcclosure(lua_State L, lua_CFunction fn, int n) { lua_lock(L); if (n == 0) { imp.setfvalue(L, L.top, fn); } else { imp.api_checknelems(L, n); imp.api_check(n <= imp.MAXUPVAL, "upvalue index too large"); imp.luaC_checkGC(L); CClosure cl = imp.luaF_newCclosure(L, n); cl.f = fn; L.top -= n; while (n-- != 0) { imp.setobj2n(L, cl.upvalue[n], L.top + n); /* does not need barrier because closure is white */ } imp.setclCvalue(L, L.top, cl); } imp.api_incr_top(L); lua_unlock(L); }
/* }====================================================== */ private static void auxopen(lua_State L, CharPtr name, lua_CFunction f, lua_CFunction u) { lua_pushcfunction(L, u); lua_pushcclosure(L, f, 1); lua_setfield(L, -2, name); }
public static lua_Object lua_setfallback(CharPtr name, lua_CFunction fallback, string name_) { adjustC(0); lua_pushstring(name); lua_pushcfunction(fallback, name_); do_protectedrun(lua_setfallback_func, 1); return(Ref(new ObjectRef(top, -1))); }
public static int lua_cpcall(lua_State L, lua_CFunction func, object ud) { CCallS c = new CCallS(); c.func = func; c.ud = ud; return(luaD_pcall(L, f_Ccall, c, savestack(L, L.top), 0)); }
public static lua_CFunction lua_atpanic(lua_State L, lua_CFunction panicf) { lua_CFunction old; old = G(L).panic; G(L).panic = panicf; return(old); }
public static lua_CFunction lua_atpanic(lua_State L, lua_CFunction panicf) { lua_lock(L); lua_CFunction old = imp.G(L).panic; imp.G(L).panic = panicf; lua_unlock(L); return(old); }
public static lua_CFunction lua_atpanic(lua_State L, lua_CFunction panicf) { lua_CFunction old; lua_lock(L); old = G(L).panic; G(L).panic = panicf; lua_unlock(L); return old; }
public static lua_CFunction lua_atpanic(LuaState L, lua_CFunction panicf) { lua_CFunction old; lua_lock(L); old = G(L).panic; G(L).panic = panicf; lua_unlock(L); return(old); }
public static bool ProtectedCall(LuaState luaState, lua_CFunction function) { lock (SyncRoot) { lua_getglobal(luaState, nameof(ProtectedCall)); lua_pushcclosure(luaState, function, 0); lua_pcall(luaState, 1, 1); return(lua_toboolean(luaState) == 1); } }
public static int luaL_cpcall(lua_State L, lua_CFunction f, int nargs, int nresults) { nargs++; /* to include function itself */ lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_CPCALL); lua_insert(L, -nargs); lua_pushlightuserdata(L, f); lua_insert(L, -nargs); return(lua_pcall(L, nargs, nresults, 0)); }
/* ** Calls the function in variable pointed to by userdata in first argument ** (Userdata cannot point directly to the function because pointer to ** function is not compatible with void*.) */ private static int cpcall(lua_State L) { lua_CFunction f = ((lua_CFunction)lua_touserdata(L, 1)); //FIXME:lua_CFunction[]???lua_CFunction??? lua_remove(L, 1); /* remove f from stack */ /* restore original environment for 'cpcall' */ lua_pushglobaltable(L); lua_replace(L, LUA_ENVIRONINDEX); return(f(L)); }
public static lua_CFunction Wrap(MethodInfo Method, object Instance = null) { MethodInfo PushMethod = GetMethodInfo(() => Push(default(lua_StatePtr), null)); MethodInfo PopMethod = GetMethodInfo(() => Get(default(lua_StatePtr), 0, typeof(void))); List <Expression> LuaToCS = new List <Expression>(); ParameterInfo[] Params = Method.GetParameters(); ParameterExpression L = Expression.Parameter(typeof(lua_StatePtr), "L"); for (int i = 0; i < Params.Length; i++) { MethodCallExpression PopMethodCall = Expression.Call(PopMethod, L, Expression.Constant(i + 1), Expression.Constant(Params[i].ParameterType, typeof(Type))); LuaToCS.Add(Expression.Convert(PopMethodCall, Params[i].ParameterType)); } List <Expression> Body = new List <Expression>(); MethodCallExpression Call = null; if (Method.IsStatic) { Call = Expression.Call(Method, LuaToCS.ToArray()); } else { if (Instance == null) { throw new NotImplementedException(); } Call = Expression.Call(Expression.Constant(Instance), Method, LuaToCS.ToArray()); } if (Method.ReturnType != typeof(void)) { Body.Add(Expression.Call(PushMethod, L, Expression.Convert(Call, typeof(object)))); } else { Body.Add(Call); Body.Add(Expression.Constant(0)); } Expression CFunc = Body[0]; if (Body.Count > 1) { CFunc = Expression.Block(Body.ToArray()); } lua_CFunction Func = Expression.Lambda <lua_CFunction>(CFunc, L).Compile(); DelegateHandles.Add(GCHandle.Alloc(Func)); return(Func); }
public static lua_CFunction lua_atpanic(IntPtr L, lua_CFunction panicf) { IntPtr pfunc = (panicf == null) ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(panicf); IntPtr poldfunc = NativeMethods.lua_atpanic(L, pfunc); if (poldfunc != IntPtr.Zero) { return(Marshal.GetDelegateForFunctionPointer(poldfunc, typeof(lua_CFunction)) as lua_CFunction); } return(null); }
public static lua_CFunction lua_atpanic(lua_State luaState, lua_CFunction panicf) { var ptr = Marshal.GetFunctionPointerForDelegate(panicf); var res = lua_atpanic(luaState, ptr); if (res == IntPtr.Zero) { return(null); } return(Marshal.GetDelegateForFunctionPointer <lua_CFunction> (res)); }
/// <summary>Runs the given function after a specified delay.</summary> /// <param name="luaState">Pointer to lua_State struct.</param> /// <param name="delay">How long until the function should be ran (in seconds).</param> /// <param name="function">The function to run after the specified delay.</param> public static void Simple(LuaState luaState, double delay, lua_CFunction function) { lock (SyncRoot) { lua_getglobal(luaState, nameof(timer)); lua_getfield(luaState, -1, nameof(Simple)); lua_pushnumber(luaState, delay); lua_pushcclosure(luaState, function, 0); lua_pcall(luaState, 2); } }
/* ** Push an object (tag=cfunction) to stack. Return 0 on success or 1 on error. */ public static int lua_pushcfunction(lua_CFunction fn, string name) { if ((top.minus(stack)) >= MAXSTACK - 1) { lua_error("stack overflow"); return(1); } tag(top.get(), Type.T_CFUNCTION); fvalue(top.get(), fn, name); top.inc(); return(0); }
public static int lua_cpcall(lua_State L, lua_CFunction func, object ud) { CCallS c = new CCallS(); int status; lua_lock(L); c.func = func; c.ud = ud; status = luaD_pcall(L, f_Ccall, c, savestack(L, L.top), 0); lua_unlock(L); return(status); }
public static lua_CFunction lua_tocfunction(IntPtr luaState, int index) { IntPtr ptr = lua_tocfunction_ptr(luaState, index); if (ptr == IntPtr.Zero) { return(null); } lua_CFunction function = Marshal.GetDelegateForFunctionPointer(ptr, typeof(lua_CFunction)) as lua_CFunction; return(function); }
/// <summary>Creates a new timer.</summary> /// <param name="luaState">Pointer to lua_State struct.</param> /// <param name="identifier">Identifier of the timer to adjust.</param> /// <param name="delay">The delay interval in seconds.</param> /// <param name="repetitions">The number of times to repeat the timer (use 0 for infinite repetitions).</param> /// <param name="function">Function to call when timer has finished the countdown.</param> public static void Create(LuaState luaState, object identifier, double delay, uint repetitions, lua_CFunction function) { lock (SyncRoot) { lua_getglobal(luaState, nameof(timer)); lua_getfield(luaState, -1, nameof(Create)); lua_pushobject(luaState, identifier); lua_pushnumber(luaState, delay); lua_pushnumber(luaState, repetitions); lua_pushcclosure(luaState, function, 0); lua_pcall(luaState, 4); } }
public static int lua_pcallk(lua_State L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k) { CallS c = new CallS(); int status; ptrdiff_t func; lua_lock(L); api_check(L, k == null || isLua(L.ci) == 0, "cannot use continuations inside hooks"); api_checknelems(L, nargs + 1); api_check(L, L.status == LUA_OK, "cannot do calls on non-normal thread"); checkresults(L, nargs, nresults); if (errfunc == 0) { func = 0; } else { StkId o = index2addr(L, errfunc); api_checkstackindex(L, errfunc, o); func = savestack(L, o); } c.func = L.top - (nargs + 1); /* function to be called */ if (k == null || L.nny > 0) /* no continuation or no yieldable? */ { c.nresults = nresults; /* do a 'conventional' protected call */ status = luaD_pcall(L, f_call, c, savestack(L, c.func), func); } else /* prepare continuation (call is already protected by 'resume') */ { CallInfo ci = L.ci; ci.u.c.k = k; /* save continuation */ ci.u.c.ctx = ctx; /* save context */ /* save information for error recovery */ ci.extra = savestack(L, c.func); ci.u.c.old_allowhook = L.allowhook; ci.u.c.old_errfunc = L.errfunc; L.errfunc = func; /* mark that function may do error recovery */ ci.callstatus |= CIST_YPCALL; luaD_call(L, c.func, nresults, 1); /* do the call */ ci.callstatus &= (byte)((~CIST_YPCALL) & 0xff); L.errfunc = ci.u.c.old_errfunc; status = LUA_OK; /* if it is here, there were no errors */ } adjustresults(L, nresults); lua_unlock(L); return(status); }
/// <summary>Adjusts the timer if the timer with the given identifier exists.</summary> /// <param name="luaState">Pointer to lua_State struct.</param> /// <param name="identifier">Identifier of the timer to adjust.</param> /// <param name="delay">The delay interval in seconds.</param> /// <param name="repetitions">Repetitions. Use 0 for infinite.</param> /// <param name="function">The new function.</param> /// <returns>True if succeeded; otherwise false.</returns> public static bool Adjust(LuaState luaState, object identifier, double delay, uint repetitions, lua_CFunction function) { lock (SyncRoot) { lua_getglobal(luaState, nameof(timer)); lua_getfield(luaState, -1, nameof(Adjust)); lua_pushobject(luaState, identifier); lua_pushnumber(luaState, delay); lua_pushnumber(luaState, repetitions); lua_pushcclosure(luaState, function, 0); lua_pcall(luaState, 4, 1); return lua_toboolean(luaState) == 1; } }
/* ** This function will use either 'ipairsaux' or 'ipairsaux_raw' to ** traverse a table, depending on whether the table has metamethods ** that can affect the traversal. */ private static int luaB_ipairs(lua_State L) { lua_CFunction iter = (luaL_getmetafield(L, 1, "__index") != LUA_TNIL) ? (lua_CFunction)ipairsaux : ipairsaux_raw; //#if defined(LUA_COMPAT_IPAIRS) return(pairsmeta(L, "__ipairs", 1, iter)); //#else // lua_pushcfunction(L, iter); /* iteration function */ // lua_pushvalue(L, 1); /* state */ // lua_pushinteger(L, 0); /* initial value */ // return 3; //#endif }
public IntPtr MarshalManagedToNative(object ManagedObj) { lua_CFunction F = (lua_CFunction)ManagedObj; if (lua_CFunction_Handles == null) { lua_CFunction_Handles = new Dictionary <lua_CFunction, GCHandle>(); } if (!lua_CFunction_Handles.ContainsKey(F)) { lua_CFunction_Handles.Add(F, GCHandle.Alloc(F)); } return(Marshal.GetFunctionPointerForDelegate(F)); }
/* ** Call a C function. CBase will point to the top of the stack, ** and CnResults is the number of parameters. Returns an index ** to the first result from C. */ private static StkId callC(lua_CFunction func, StkId @base) { StkId oldBase = CBase; int oldCnResults = CnResults; StkId firstResult; CnResults = ObjectRef.minus(top, stack) - @base; /* incorporate parameters on the stack */ CBase = @base + CnResults; func(); firstResult = CBase; CBase = oldBase; CnResults = oldCnResults; return(firstResult); }
public static void lua_pushcclosure(lua_State L, lua_CFunction fn, int n) { Closure cl; luaC_checkGC(L); api_checknelems(L, n); cl = luaF_newCclosure(L, n, getcurrenv(L)); cl.c.f = fn; L.top -= n; while (n-- != 0) { setobj2n(L, cl.c.upvalue[n], L.top + n); } setclvalue(L, L.top, cl); lua_assert(iswhite(obj2gco(cl))); api_incr_top(L); }
/* ** stripped-down 'require'. Calls 'openf' to open a module, ** registers the result in 'package.loaded' table and, if 'glb' ** is true, also registers the result in the global table. ** Leaves resulting module on the top. */ public static void luaL_requiref(lua_State L, CharPtr modname, lua_CFunction openf, int glb) { lua_pushcfunction(L, openf); lua_pushstring(L, modname); /* argument to open function */ lua_call(L, 1, 1); /* open module */ luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_pushvalue(L, -2); /* make copy of module (call result) */ lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ lua_pop(L, 1); /* remove _LOADED table */ if (glb != 0) { lua_pushglobaltable(L); lua_pushvalue(L, -2); /* copy of 'mod' */ lua_setfield(L, -2, modname); /* _G[modname] = module */ lua_pop(L, 1); /* remove _G table */ } }
/* ** Stripped-down 'require': After checking "loaded" table, calls 'openf' ** to open a module, registers the result in 'package.loaded' table and, ** if 'glb' is true, also registers the result in the global table. ** Leaves resulting module on the top. */ public static void luaL_requiref(lua_State L, string modname, lua_CFunction openf, int glb) { luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(L, -1, modname); /* _LOADED[modname] */ if (lua_toboolean(L, -1) == 0) /* package not already loaded? */ { lua_pop(L, 1); /* remove field */ lua_pushcfunction(L, openf); lua_pushstring(L, modname); /* argument to open function */ lua_call(L, 1, 1); /* call 'openf' to open module */ lua_pushvalue(L, -1); /* make copy of module (call result) */ lua_setfield(L, -3, modname); /* _LOADED[modname] = module */ } lua_remove(L, -2); /* remove _LOADED table */ if (glb != 0) { lua_pushvalue(L, -1); /* copy of module */ lua_setglobal(L, modname); /* _G[modname] = module */ } }
/* * private static int luaB_next(LuaState L) * { * luaL_checktype(L, 1, LUA_TTABLE); * lua_settop(L, 2); // create a 2nd argument if there isn't one * if (lua_next(L, 1) != 0) * return 2; * else * { * lua_pushnil(L); * return 1; * } * } * * private static int luaB_pairs(LuaState L) * { * luaL_checktype(L, 1, LUA_TTABLE); * lua_pushvalue(L, lua_upvalueindex(1)); // return generator, * lua_pushvalue(L, 1); // state, * lua_pushnil(L); // and initial value * return 3; * } * * * private static int ipairsaux(LuaState L) * { * int i = luaL_checkint(L, 2); * luaL_checktype(L, 1, LUA_TTABLE); * i++; // next value * lua_pushinteger(L, i); * lua_rawgeti(L, 1, i); * return (lua_isnil(L, -1)) ? 0 : 2; * } */ static int pairsmeta(LuaState L, CharPtr method, bool iszero, lua_CFunction iter) { if (luaL_getmetafield(L, 1, method) == 0) { /* no metamethod? */ luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ lua_pushcfunction(L, iter); /* will return generator, */ lua_pushvalue(L, 1); /* state, */ if (iszero) { lua_pushinteger(L, 0); /* and initial value */ } else { lua_pushnil(L); } } else { lua_pushvalue(L, 1); /* argument 'self' to metamethod */ lua_call(L, 1, 3); /* get 3 values from metamethod */ } return(3); }
private static int pairsmeta(lua_State L, CharPtr method, int iszero, lua_CFunction iter) { luaL_checkany(L, 1); if (luaL_getmetafield(L, 1, method) == LUA_TNIL) /* no metamethod? */ { lua_pushcfunction(L, iter); /* will return generator, */ lua_pushvalue(L, 1); /* state, */ if (iszero != 0) { lua_pushinteger(L, 0); /* and initial value */ } else { lua_pushnil(L); } } else { lua_pushvalue(L, 1); /* argument 'self' to metamethod */ lua_call(L, 1, 3); /* get 3 values from metamethod */ } return(3); }
public luaL_Reg(CharPtr name, lua_CFunction func) { this.name = name; this.func = func; }
public static extern void lua_register(IntPtr state, string name, lua_CFunction f);
public static extern void lua_pushcclosure(LuaState luaState, lua_CFunction fn, int n);
private static void newfenv (lua_State L, lua_CFunction cls) { lua_createtable(L, 0, 1); lua_pushcfunction(L, cls); lua_setfield(L, -2, "__close"); }
public static extern int lua_pcallk(IntPtr state, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k);
public static extern void lua_callk(IntPtr state, int nargs, int nresults, int ctx, lua_CFunction k);
public static bool ProtectedCall(LuaState luaState, lua_CFunction function) { lock (SyncRoot) { lua_getglobal(luaState, nameof(ProtectedCall)); lua_pushcclosure(luaState, function, 0); lua_pcall(luaState, 1, 1); return lua_toboolean(luaState) == 1; } }
public static extern int lua_yeildk(IntPtr state, int nresult, int ctx, lua_CFunction k);
public static void RegisterCFunction(string tableName, string funcName, lua_CFunction function) => RegisterCFunction(_state, tableName, funcName, function);
public static void lua_pushcclosure(lua_CFunction fn, int n) => lua_pushcclosure(_state, fn, n);
public static unsafe int lua_cpcall(lua_CFunction func, void* ud) => lua_cpcall(_state, func, ud);
public static lua_CFunction lua_atpanic(lua_CFunction panicf) => lua_atpanic(_state, panicf);
public static void RegisterCFunction(LuaState luaState, string tableName, string funcName, lua_CFunction function) { lua_getfield(luaState, (int)TableIndex.SpecialGlob, tableName); if (!lua_type(luaState, -1, Type.Table)) { lua_createtable(luaState, 0, 1); lua_setglobal(luaState, tableName); lua_pop(luaState); lua_getglobal(luaState, tableName); } lua_pushstring(luaState, funcName); lua_pushcclosure(luaState, function, 0); lua_settable(luaState, -3); lua_pop(luaState); }
public static extern void lua_pushcclosure(IntPtr L, lua_CFunction fn, int n);
public static void lua_pushcfunction(IntPtr L, lua_CFunction f) { lua_pushcclosure(L, f, 0); }
public static void setfvalue(TValue obj, lua_CFunction x) { TValue io = obj; io.value_.f = x; settt_(io, LUA_TLCF); } //FIXME:chagned, val_(io)
public static extern void lua_pushcfunction(IntPtr state, lua_CFunction f);
public static void lua_pushcclosure(lua_State L, lua_CFunction fn, int n) { Closure cl; lua_lock(L); luaC_checkGC(L); api_checknelems(L, n); cl = luaF_newCclosure(L, n, getcurrenv(L)); cl.c.f = fn; L.top -= n; while (n-- != 0) setobj2n(L, cl.c.upvalue[n], L.top+n); setclvalue(L, L.top, cl); lua_assert(iswhite(obj2gco(cl))); api_incr_top(L); lua_unlock(L); }
/* }====================================================== */ private static void auxopen(LuaState L, CharPtr name, lua_CFunction f, lua_CFunction u) { lua_pushcfunction(L, u); lua_pushcclosure(L, f, 1); lua_setfield(L, -2, name); }
public static extern int lua_cpcall(lua_State L, lua_CFunction func, IntPtr ud);
public static extern lua_CFunction lua_atpanic(IntPtr state, lua_CFunction panicf);
public static extern lua_CFunction lua_atpanic(LuaState luaState, lua_CFunction panicf);
public static void lua_pushcfunction(lua_State L, lua_CFunction f) { lua_pushcclosure(L, f, 0); }
public static void lua_register(lua_State L, CharPtr n, lua_CFunction f) { lua_pushcfunction(L, f); lua_setglobal(L, n); }
public static int lua_cpcall(lua_State L, lua_CFunction func, object ud) { CCallS c = new CCallS(); int status; lua_lock(L); c.func = func; c.ud = ud; status = luaD_pcall(L, f_Ccall, c, savestack(L, L.top), 0); lua_unlock(L); return status; }
public static extern void luaL_requiref(lua_State L, String modname, lua_CFunction openf, int glb);
public static extern unsafe int lua_cpcall(LuaState luaState, lua_CFunction func, void* ud);
/* private static int luaB_next(LuaState L) { luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 2); // create a 2nd argument if there isn't one if (lua_next(L, 1) != 0) return 2; else { lua_pushnil(L); return 1; } } private static int luaB_pairs(LuaState L) { luaL_checktype(L, 1, LUA_TTABLE); lua_pushvalue(L, lua_upvalueindex(1)); // return generator, lua_pushvalue(L, 1); // state, lua_pushnil(L); // and initial value return 3; } private static int ipairsaux(LuaState L) { int i = luaL_checkint(L, 2); luaL_checktype(L, 1, LUA_TTABLE); i++; // next value lua_pushinteger(L, i); lua_rawgeti(L, 1, i); return (lua_isnil(L, -1)) ? 0 : 2; } */ static int pairsmeta(LuaState L, CharPtr method, bool iszero, lua_CFunction iter) { if (luaL_getmetafield(L, 1, method) == 0) { /* no metamethod? */ luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ lua_pushcfunction(L, iter); /* will return generator, */ lua_pushvalue(L, 1); /* state, */ if (iszero) lua_pushinteger(L, 0); /* and initial value */ else lua_pushnil(L); } else { lua_pushvalue(L, 1); /* argument 'self' to metamethod */ lua_call(L, 1, 3); /* get 3 values from metamethod */ } return 3; }