// we have a gc, so nothing to do public static void LuaFFreeClosure(LuaState L, Closure c) { int size = (c.c.isC != 0) ? SizeCclosure(c.c.nupvalues) : SizeLclosure(c.l.nupvalues); //luaM_freemem(L, c, size); SubtractTotalBytes(L, size); }
public static LuaState LuaNetGetMainState(LuaState L1) { LuaGetField (L1, LUA_REGISTRYINDEX, "main_state"); LuaState main = LuaToThread (L1, -1); LuaPop (L1, 1); return main; }
private static int CurrentLine (LuaState L, CallInfo ci) { int pc = CurrentPC(L, ci); if (pc < 0) return -1; /* only active lua functions have current-line information */ else return GetLine(CIFunc(ci).l.p, pc); }
public static int LuaNetToNetObject (LuaState luaState, int index) { byte[] udata; if (LuaType (luaState, index) == LUA_TUSERDATA) { if (LuaLCheckMetatable (luaState, index)) { udata = LuaToUserData (luaState, index) as byte[]; if (udata != null) return FourBytesToInt (udata); } udata = CheckUserDataRaw (luaState, index, "luaNet_class") as byte[]; if (udata != null) return FourBytesToInt (udata); udata = CheckUserDataRaw (luaState, index, "luaNet_searchbase") as byte[]; if (udata != null) return FourBytesToInt (udata); udata = CheckUserDataRaw (luaState, index, "luaNet_function") as byte[]; if (udata != null) return FourBytesToInt (udata); } return -1; }
// Starting with 5.1 the auxlib version of checkudata throws an exception if the type isn't right // Instead, we want to run our own version that checks the type and just returns null for failure private static object CheckUserDataRaw (LuaState L, int ud, string tname) { object p = LuaToUserData (L, ud); if (p != null) { /* value is a userdata? */ if (LuaGetMetatable (L, ud) != 0) { bool isEqual; /* does it have a metatable? */ LuaGetField (L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ isEqual = LuaRawEqual (L, -1, -2) != 0; // NASTY - we need our own version of the lua_pop macro // lua_pop(L, 2); /* remove both metatables */ LuaSetTop (L, -(2) - 1); if (isEqual) /* does it have the correct mt? */ return p; } } return null; }
public static void LuaDCallHook(LuaState L, int event_, int line) { LuaHook hook = L.hook; if ((hook != null) && (L.allowhook != 0)) { ptrdiff_t top = SaveStack(L, L.top); ptrdiff_t ci_top = SaveStack(L, L.ci.top); LuaDebug ar = new LuaDebug(); ar.event_ = event_; ar.currentline = line; if (event_ == LUA_HOOKTAILRET) ar.i_ci = 0; /* tail call; no debug information about it */ else ar.i_ci = L.ci - L.base_ci; LuaDCheckStack(L, LUA_MINSTACK); /* ensure minimum stack size */ L.ci.top = L.top + LUA_MINSTACK; LuaAssert(L.ci.top <= L.stack_last); L.allowhook = 0; /* cannot call hooks inside a hook */ LuaUnlock(L); hook(L, ar); LuaLock(L); LuaAssert(L.allowhook == 0); L.allowhook = 1; L.ci.top = RestoreStack(L, ci_top); L.top = RestoreStack(L, top); } }
private static int LuaBToNumber (LuaState L) { int base_ = LuaLOptInt(L, 2, 10); if (base_ == 10) { /* standard conversion */ LuaLCheckAny(L, 1); if (LuaIsNumber(L, 1) != 0) { LuaPushNumber(L, LuaToNumber(L, 1)); return 1; } } else { CharPtr s1 = LuaLCheckString(L, 1); CharPtr s2; ulong n; LuaLArgCheck(L, 2 <= base_ && base_ <= 36, 2, "base out of range"); n = strtoul(s1, out s2, base_); if (s1 != s2) { /* at least one valid digit? */ while (isspace((byte)(s2[0]))) s2 = s2.next(); /* skip trailing spaces */ if (s2[0] == '\0') { /* no invalid trailing characters? */ LuaPushNumber(L, (LuaNumberType)n); return 1; } } } LuaPushNil(L); /* else not a number */ return 1; }
public static void luaH_free(LuaState L, Table t) { if (t.node[0] != dummynode) LuaMFreeArray(L, t.node); LuaMFreeArray(L, t.array); LuaMFree(L, t); }
public static TString newlstr (LuaState L, CharPtr str, uint l, uint h) { TString ts; stringtable tb; if (l+1 > MAXSIZET /GetUnmanagedSize(typeof(char))) LuaMTooBig(L); ts = new TString(new char[l+1]); AddTotalBytes(L, (int)(l + 1) * GetUnmanagedSize(typeof(char)) + GetUnmanagedSize(typeof(TString))); ts.tsv.len = l; ts.tsv.hash = h; ts.tsv.marked = LuaCWhite(G(L)); ts.tsv.tt = LUA_TSTRING; ts.tsv.reserved = 0; //memcpy(ts+1, str, l*GetUnmanagedSize(typeof(char))); memcpy(ts.str.chars, str.chars, str.index, (int)l); ts.str[l] = '\0'; /* ending 0 */ tb = G(L).strt; h = (uint)lmod(h, tb.size); ts.tsv.next = tb.hash[h]; /* chain new entry */ tb.hash[h] = obj2gco(ts); tb.nuse++; if ((tb.nuse > (int)tb.size) && (tb.size <= MAXINT/2)) luaS_resize(L, tb.size*2); /* too crowded */ return ts; }
static TValue Index2Address (LuaState L, int idx) { if (idx > 0) { TValue o = L.base_ + (idx - 1); ApiCheck(L, idx <= L.ci.top - L.base_); if (o >= L.top) return LuaONilObject; else return o; } else if (idx > LUA_REGISTRYINDEX) { ApiCheck(L, idx != 0 && -idx <= L.top - L.base_); return L.top + idx; } else switch (idx) { /* pseudo-indices */ case LUA_REGISTRYINDEX: return Registry(L); case LUA_ENVIRONINDEX: { Closure func = CurrFunc(L); SetHValue(L, L.env, func.c.env); return L.env; } case LUA_GLOBALSINDEX: return Gt(L); default: { Closure func = CurrFunc(L); idx = LUA_GLOBALSINDEX - idx; return (idx <= func.c.nupvalues) ? func.c.upvalue[idx-1] : (TValue)LuaONilObject; } } }
/* * Pushes the function into the Lua stack */ internal void Push(LuaState luaState) { if (_Reference != 0) LuaLib.LuaGetRef(luaState, _Reference); else _Interpreter.PushCSFunction(function); }
static Lua.Proto combine(LuaState L, int n) { if (n==1) return toproto(L,-1); else { int i,pc; Lua.Proto f=Lua.LuaFNewProto(L); Lua.SetPTValue2S(L,L.top,f); Lua.IncrTop(L); f.source=Lua.luaS_newliteral(L,"=(" + PROGNAME + ")"); f.maxstacksize=1; pc=2*n+1; f.code = (Instruction[])Lua.LuaMNewVector<Instruction>(L, pc); f.sizecode=pc; f.p = Lua.LuaMNewVector<Lua.Proto>(L, n); f.sizep=n; pc=0; for (i=0; i<n; i++) { f.p[i]=toproto(L,i-n-1); f.code[pc++]=(uint)Lua.CREATE_ABx(Lua.OpCode.OP_CLOSURE,0,i); f.code[pc++]=(uint)Lua.CREATE_ABC(Lua.OpCode.OP_CALL,0,1,1); } f.code[pc++]=(uint)Lua.CREATE_ABC(Lua.OpCode.OP_RETURN,0,1,0); return f; } }
public static UpVal LuaFNewUpVal (LuaState L) { UpVal uv = LuaMNew<UpVal>(L); LuaCLink(L, obj2gco(uv), LUATUPVAL); uv.v = uv.u.value; SetNilValue(uv.v); return uv; }
public static void LuaGArithError(LuaState L, TValue p1, TValue p2) { TValue temp = new LuaTypeValue(); if (luaV_tonumber(p1, temp) == null) p2 = p1; /* first operand is wrong */ LuaGTypeError(L, p2, "perform arithmetic on"); }
private static int DBGetMetatable (LuaState L) { LuaLCheckAny(L, 1); if (LuaGetMetatable(L, 1) == 0) { LuaPushNil(L); /* no metatable */ } return 1; }
public static UpVal LuaFindUpVal (LuaState L, StkId level) { GlobalState g = G(L); GCObjectRef pp = new OpenValRef(L); UpVal p; UpVal uv; while (pp.get() != null && (p = ngcotouv(pp.get())).v >= level) { LuaAssert(p.v != p.u.value); if (p.v == level) { /* found a corresponding upvalue? */ if (IsDead(g, obj2gco(p))) /* is it dead? */ ChangeWhite(obj2gco(p)); /* ressurect it */ return p; } pp = new NextRef(p); } uv = LuaMNew<UpVal>(L); /* not found: create a new one */ uv.tt = LUATUPVAL; uv.marked = LuaCWhite(g); uv.v = level; /* current value lives in the stack */ uv.next = pp.get(); /* chain it in the proper position */ pp.set( obj2gco(uv) ); uv.u.l.prev = g.uvhead; /* double link it in `uvhead' list */ uv.u.l.next = g.uvhead.u.l.next; uv.u.l.next.u.l.prev = uv; g.uvhead.u.l.next = uv; LuaAssert(uv.u.l.next.u.l.prev == uv && uv.u.l.prev.u.l.next == uv); return uv; }
public ObjectTranslator Find(LuaState luaState) { if (!translators.ContainsKey(luaState)) return null; return translators[luaState]; }
//public static void setprogdir(LuaState L) { } public static void SetProgDir(LuaState L) { #if WINDOWS_PHONE // On Windows Phone, the current directory is the root of the // Isolated Storage directory, which is "/". CharPtr buff = "/"; #elif SILVERLIGHT // Not all versions of Silverlight support this method. // So, if it is unsupported, rollback to the Isolated // Storage root (a.k.a. the leap of faith). CharPtr buff; try { buff = Directory.GetCurrentDirectory(); } catch (MethodAccessException) { buff = "/"; } #else CharPtr buff = Directory.GetCurrentDirectory(); #endif LuaLGSub(L, LuaToString(L, -1), LUA_EXECDIR, buff); LuaRemove(L, -2); /* remove original string */ }
public static void luaT_init (LuaState L) { int i; for (i=0; i<(int)TMS.TM_N; i++) { G(L).tmname[i] = luaS_new(L, luaT_eventname[i]); luaS_fix(G(L).tmname[i]); /* never collect these names */ } }
public void Remove(LuaState luaState) { if (!translators.ContainsKey(luaState)) return; translators.Remove(luaState); }
public static void luaS_resize (LuaState L, int newsize) { GCObject[] newhash; stringtable tb; int i; if (G(L).gcstate == GCSsweepstring) return; /* cannot resize during GC traverse */ newhash = new GCObject[newsize]; AddTotalBytes(L, newsize * GetUnmanagedSize(typeof(GCObjectRef))); tb = G(L).strt; for (i=0; i<newsize; i++) newhash[i] = null; /* rehash */ for (i=0; i<tb.size; i++) { GCObject p = tb.hash[i]; while (p != null) { /* for each node in the list */ GCObject next = p.gch.next; /* save next */ uint h = gco2ts(p).hash; int h1 = (int)lmod(h, newsize); /* new position */ LuaAssert((int)(h%newsize) == lmod(h, newsize)); p.gch.next = newhash[h1]; /* chain it */ newhash[h1] = p; p = next; } } //luaM_freearray(L, tb.hash); if (tb.hash != null) SubtractTotalBytes(L, tb.hash.Length * GetUnmanagedSize(typeof(GCObjectRef))); tb.size = newsize; tb.hash = newhash; }
public static CallInfo IncCI(LuaState L) { if (L.ci == L.end_ci) return GrowCI(L); // (condhardstacktests(luaD_reallocCI(L, L.size_ci)), ++L.ci)) CallInfo.Inc(ref L.ci); return L.ci; }
public static void luaZ_resizebuffer(LuaState L, Mbuffer buff, int size) { if (buff.buffer == null) buff.buffer = new CharPtr(); LuaMReallocVector(L, ref buff.buffer.chars, (int)buff.buffsize, size); buff.buffsize = (uint)buff.buffer.chars.Length; }
private static void addfield(LuaState L, LuaLBuffer b, int i) { LuaRawGetI(L, 1, i); if (LuaIsString(L, -1)==0) LuaLError(L, "invalid value (%s) at index %d in table for " + LUA_QL("concat"), LuaLTypeName(L, -1), i); LuaLAddValue(b); }
private static int DBSetMetatable (LuaState L) { int t = LuaType(L, 2); LuaLArgCheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table expected"); LuaSetTop(L, 2); LuaPushBoolean(L, LuaSetMetatable(L, 1)); return 1; }
private static int DBSetFEnv (LuaState L) { LuaLCheckType(L, 2, LUA_TTABLE); LuaSetTop(L, 2); if (LuaSetFEnv(L, 1) == 0) LuaLError(L, LUA_QL("setfenv") + " cannot change environment of given object"); return 1; }
private static int OSTmpName (LuaState L) { #if XBOX LuaLError(L, "os_tmpname not supported on Xbox360"); #else LuaPushString(L, Path.GetTempFileName()); #endif return 1; }
private static Table GetCurrentEnv (LuaState L) { if (L.ci == L.base_ci[0]) /* no enclosing function? */ return HValue(Gt(L)); /* use global table as environment */ else { Closure func = CurrFunc(L); return func.c.env; } }
public static void luaZ_init(LuaState L, ZIO z, lua_Reader reader, object data) { z.L = L; z.reader = reader; z.data = data; z.n = 0; z.p = null; }
private static int GetBoolField(LuaState L, CharPtr key) { int res; LuaGetField(L, -1, key); res = LuaIsNil(L, -1) ? -1 : LuaToBoolean(L, -1); LuaPop(L, 1); return res; }
public static void IncrTop(LuaState L) { LuaDCheckStack(L, 1); StkId.Inc(ref L.top); }
// in the original C code these values save and restore the stack by number of bytes. marshalling sizeof // isn't that straightforward in managed languages, so i implement these by index instead. public static int SaveStack(LuaState L, StkId p) { return(p); }
private static int LuaBYield(LuaState L) { return(LuaYield(L, LuaGetTop(L))); }
/* ** {====================================================== ** Time/Date operations ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, ** wday=%w+1, yday=%j, isdst=? } ** ======================================================= */ private static void SetField(LuaState L, CharPtr key, int value) { LuaPushInteger(L, value); LuaSetField(L, -2, key); }
private static int LuaBGGInfo(LuaState L) { LuaPushInteger(L, LuaGetGCCount(L)); return(1); }
private static int LuaBType(LuaState L) { LuaLCheckAny(L, 1); LuaPushString(L, LuaLTypeName(L, 1)); return(1); }
private static int auxsort_loop2(LuaState L, ref int j) { LuaRawGetI(L, 1, --j); return(sort_comp(L, -3, -1)); }
private static int OSGetEnv(LuaState L) { LuaPushString(L, getenv(LuaLCheckString(L, 1))); /* if null push nil */ return(1); }
private static int LuaBLoadFile(LuaState L) { CharPtr fname = LuaLOptString(L, 1, null); return(LoadAux(L, LuaLLoadFile(L, fname))); }
public static int LuaDPreCall(LuaState L, StkId func, int nresults) { LClosure cl; ptrdiff_t funcr; if (!TTIsFunction(func)) /* `func' is not a function? */ { func = TryFuncTM(L, func); /* check the `function' tag method */ } funcr = SaveStack(L, func); cl = CLValue(func).l; L.ci.savedpc = InstructionPtr.Assign(L.savedpc); if (cl.isC == 0) /* Lua function? prepare its call */ { CallInfo ci; StkId st, base_; Proto p = cl.p; LuaDCheckStack(L, p.maxstacksize); func = RestoreStack(L, funcr); if (p.is_vararg == 0) /* no varargs? */ { base_ = L.stack[func + 1]; if (L.top > base_ + p.numparams) { L.top = base_ + p.numparams; } } else /* vararg function */ { int nargs = L.top - func - 1; base_ = AdjustVarArgs(L, p, nargs); func = RestoreStack(L, funcr); /* previous call may change the stack */ } ci = IncCI(L); /* now `enter' new function */ ci.func = func; L.base_ = ci.base_ = base_; ci.top = L.base_ + p.maxstacksize; LuaAssert(ci.top <= L.stack_last); L.savedpc = new InstructionPtr(p.code, 0); /* starting point */ ci.tailcalls = 0; ci.nresults = nresults; for (st = L.top; st < ci.top; StkId.Inc(ref st)) { SetNilValue(st); } L.top = ci.top; if ((L.hookmask & LUA_MASKCALL) != 0) { InstructionPtr.inc(ref L.savedpc); /* hooks assume 'pc' is already incremented */ LuaDCallHook(L, LUA_HOOKCALL, -1); InstructionPtr.dec(ref L.savedpc); /* correct 'pc' */ } return(PCRLUA); } else /* if is a C function, call it */ { CallInfo ci; int n; LuaDCheckStack(L, LUA_MINSTACK); /* ensure minimum stack size */ ci = IncCI(L); /* now `enter' new function */ ci.func = RestoreStack(L, funcr); L.base_ = ci.base_ = ci.func + 1; ci.top = L.top + LUA_MINSTACK; LuaAssert(ci.top <= L.stack_last); ci.nresults = nresults; if ((L.hookmask & LUA_MASKCALL) != 0) { LuaDCallHook(L, LUA_HOOKCALL, -1); } LuaUnlock(L); n = CurrFunc(L).c.f(L); /* do the actual call */ LuaLock(L); if (n < 0) /* yielding? */ { return(PCRYIELD); } else { LuaDPosCall(L, L.top - n); return(PCRC); } } }
/* }====================================================== */ public static int LuaOpenOS(LuaState L) { LuaLRegister(L, LUA_OSLIBNAME, syslib); return(1); }
public static CallInfo RestoreCI(LuaState L, int n) { return(L.base_ci[n]); }
public static int SaveCI(LuaState L, CallInfo p) { return(p - L.base_ci); }
public static StkId RestoreStack(LuaState L, int n) { return(L.stack[n]); }
private static int OSDate(LuaState L) { CharPtr s = new CharPtr(LuaLOptString(L, 1, "%c")); DateTime stm; // Parses the second argument if there's one. If not, uses Now as time. if (LuaIsNoneOrNil(L, 2)) { stm = DateTime.Now; } else { LuaLCheckType(L, 2, LUA_TNUMBER); double seconds = LuaToNumber(L, 2); stm = new DateTime((long)seconds * TimeSpan.TicksPerSecond); } if (s[0] == '!') /* UTC? */ { stm = stm.ToUniversalTime(); s.inc(); /* skip `!' */ } if (strcmp(s, "*t") == 0) { LuaCreateTable(L, 0, 9); /* 9 = number of fields */ SetField(L, "sec", stm.Second); SetField(L, "min", stm.Minute); SetField(L, "hour", stm.Hour); SetField(L, "day", stm.Day); SetField(L, "month", stm.Month); SetField(L, "year", stm.Year); SetField(L, "wday", (int)stm.DayOfWeek + 1); SetField(L, "yday", stm.DayOfYear); SetBoolField(L, "isdst", stm.IsDaylightSavingTime() ? 1 : 0); } else { CharPtr cc = new char[3]; LuaLBuffer b = new LuaLBuffer(); cc[0] = '%'; cc[2] = '\0'; LuaLBuffInit(L, b); for (; s[0] != 0; s.inc()) { if (s[0] != '%' || s[1] == '\0') /* no conversion specifier? */ { LuaLAddChar(b, s[0]); } else { uint reslen; CharPtr buff = new char[200]; /* should be big enough for any conversion result */ s.inc(); cc[1] = s[0]; reslen = strftime(buff, (uint)buff.chars.Length, cc, stm); buff.index = 0; LuaLAddLString(b, buff, reslen); } } LuaLPushResult(b); } return(1); }
private static int LuaBCoWrap(LuaState L) { LuaBCoCreate(L); LuaPushCClosure(L, LuaBAuxWrap, 1); return(1); }
public static int luaopen_table(LuaState L) { LuaLRegister(L, LUA_TABLIBNAME, tab_funcs); return(1); }
private static int getn(LuaState L) { LuaPushInteger(L, aux_getn(L, 1)); return(1); }
public static int LuaOpenBase(LuaState L) { BaseOpen(L); LuaLRegister(L, LUA_COLIBNAME, co_funcs); return(2); }
private static void auxsort(LuaState L, int l, int u) { while (l < u) /* for tail recursion */ { int i, j; /* sort elements a[l], a[(l+u)/2] and a[u] */ LuaRawGetI(L, 1, l); LuaRawGetI(L, 1, u); if (sort_comp(L, -1, -2) != 0) /* a[u] < a[l]? */ { set2(L, l, u); /* swap a[l] - a[u] */ } else { LuaPop(L, 2); } if (u - l == 1) { break; /* only 2 elements */ } i = (l + u) / 2; LuaRawGetI(L, 1, i); LuaRawGetI(L, 1, l); if (sort_comp(L, -2, -1) != 0) /* a[i]<a[l]? */ { set2(L, i, l); } else { LuaPop(L, 1); /* remove a[l] */ LuaRawGetI(L, 1, u); if (sort_comp(L, -1, -2) != 0) /* a[u]<a[i]? */ { set2(L, i, u); } else { LuaPop(L, 2); } } if (u - l == 2) { break; /* only 3 elements */ } LuaRawGetI(L, 1, i); /* Pivot */ LuaPushValue(L, -1); LuaRawGetI(L, 1, u - 1); set2(L, i, u - 1); /* a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */ i = l; j = u - 1; for (;;) /* invariant: a[l..i] <= P <= a[j..u] */ /* repeat ++i until a[i] >= P */ { while (auxsort_loop1(L, ref i) != 0) { if (i > u) { LuaLError(L, "invalid order function for sorting"); } LuaPop(L, 1); /* remove a[i] */ } /* repeat --j until a[j] <= P */ while (auxsort_loop2(L, ref j) != 0) { if (j < l) { LuaLError(L, "invalid order function for sorting"); } LuaPop(L, 1); /* remove a[j] */ } if (j < i) { LuaPop(L, 3); /* pop pivot, a[i], a[j] */ break; } set2(L, i, j); } LuaRawGetI(L, 1, u - 1); LuaRawGetI(L, 1, i); set2(L, u - 1, i); /* swap pivot (a[u-1]) with a[i] */ /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ /* adjust so that smaller half is in [j..i] and larger one in [l..u] */ if (i - l < u - i) { j = l; i = i - 1; l = i + 2; } else { j = i + 1; i = u; u = j - 2; } auxsort(L, j, i); /* call recursively the smaller one */ } /* repeat the routine for the larger one */ }
/* ** {====================================================== ** Quicksort ** (based on `Algorithms in MODULA-3', Robert Sedgewick; ** Addison-Wesley, 1993.) */ private static void set2(LuaState L, int i, int j) { LuaRawSetI(L, 1, i); LuaRawSetI(L, 1, j); }
public static void luaH_resizearray(LuaState L, Table t, int nasize) { int nsize = (t.node[0] == dummynode) ? 0 : SizeNode(t); resize(L, t, nasize, nsize); }
private static int aux_getn(LuaState L, int n) { LuaLCheckType(L, n, LUA_TTABLE); return(LuaLGetN(L, n)); }
private static int auxsort_loop1(LuaState L, ref int i) { LuaRawGetI(L, 1, ++i); return(sort_comp(L, -1, -2)); }