Пример #1
0
        /*
        ** {======================================================
        ** Error-report functions
        ** =======================================================
        */


        public static int LinyeeLArgError(LinyeeState L, int narg, CharPtr extramsg)
        {
            LinyeeDebug ar = new LinyeeDebug();

            if (LinyeeGetStack(L, 0, ref ar) == 0)      /* no stack frame? */
            {
                return(LinyeeLError(L, "bad argument #%d (%s)", narg, extramsg));
            }
            LinyeeGetInfo(L, "n", ref ar);
            if (strcmp(ar.namewhat, "method") == 0)
            {
                narg--;          /* do not count `self' */
                if (narg == 0)   /* error is in the self argument itself? */
                {
                    return(LinyeeLError(L, "calling " + LINYEE_QS + " on bad self ({1})",
                                        ar.name, extramsg));
                }
            }
            if (ar.name == null)
            {
                ar.name = "?";
            }
            return(LinyeeLError(L, "bad argument #%d to " + LINYEE_QS + " (%s)",
                                narg, ar.name, extramsg));
        }
Пример #2
0
        public static int LinyeeGetStack(LinyeeState L, int level, ref LinyeeDebug ar)
        {
            int      status;
            CallInfo ci;

            LinyeeLock(L);
            for (ci = L.ci; level > 0 && ci > L.base_ci[0]; CallInfo.Dec(ref ci))
            {
                level--;
                if (FIsLinyee(ci))          /* Linyee function? */
                {
                    level -= ci.tailcalls;  /* skip lost tail calls */
                }
            }
            if (level == 0 && ci > L.base_ci[0])          /* level found? */
            {
                status  = 1;
                ar.i_ci = ci - L.base_ci[0];
            }
            else if (level < 0)          /* level is of a lost tail call? */
            {
                status  = 1;
                ar.i_ci = 0;
            }
            else
            {
                status = 0;         /* no such level */
            }
            LinyeeUnlock(L);
            return(status);
        }
Пример #3
0
        private static int costatus(LinyeeState L, LinyeeState co)
        {
            if (L == co)
            {
                return(CO_RUN);
            }
            switch (LinyeeStatus(co))
            {
            case LINYEE_YIELD:
                return(CO_SUS);

            case 0: {
                LinyeeDebug ar = new LinyeeDebug();
                if (LinyeeGetStack(co, 0, ref ar) > 0) /* does it have frames? */
                {
                    return(CO_NOR);                    /* it is running */
                }
                else if (LinyeeGetTop(co) == 0)
                {
                    return(CO_DEAD);
                }
                else
                {
                    return(CO_SUS);             /* initial state */
                }
            }

            default:              /* some error occured */
                return(CO_DEAD);
            }
        }
Пример #4
0
        public static void LinyeeDCallHook(LinyeeState L, int event_, int line)
        {
            LinyeeHook 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);
                LinyeeDebug ar     = new LinyeeDebug();
                ar.event_      = event_;
                ar.currentline = line;
                if (event_ == LINYEE_HOOKTAILRET)
                {
                    ar.i_ci = 0;        /* tail call; no debug information about it */
                }
                else
                {
                    ar.i_ci = L.ci - L.base_ci;
                }
                LinyeeDCheckStack(L, LINYEE_MINSTACK);          /* ensure minimum stack size */
                L.ci.top = L.top + LINYEE_MINSTACK;
                LinyeeAssert(L.ci.top <= L.stack_last);
                L.allowhook = 0;          /* cannot call hooks inside a hook */
                LinyeeUnlock(L);
                hook(L, ar);
                LinyeeLock(L);
                LinyeeAssert(L.allowhook == 0);
                L.allowhook = 1;
                L.ci.top    = RestoreStack(L, ci_top);
                L.top       = RestoreStack(L, top);
            }
        }
Пример #5
0
        private static int DBGetLocal(LinyeeState L)
        {
            int         arg;
            LinyeeState L1 = GetThread(L, out arg);
            LinyeeDebug ar = new LinyeeDebug();
            CharPtr     name;

            if (LinyeeGetStack(L1, LinyeeLCheckInt(L, arg + 1), ref ar) == 0)    /* out of range? */
            {
                return(LinyeeLArgError(L, arg + 1, "level out of range"));
            }
            name = LinyeeGetLocal(L1, ar, LinyeeLCheckInt(L, arg + 2));
            if (name != null)
            {
                LinyeeXMove(L1, L, 1);
                LinyeePushString(L, name);
                LinyeePushValue(L, -2);
                return(2);
            }
            else
            {
                LinyeePushNil(L);
                return(1);
            }
        }
Пример #6
0
 private static void InfoTailCall(LinyeeDebug ar)
 {
     ar.name            = ar.namewhat = "";
     ar.what            = "tail";
     ar.lastlinedefined = ar.linedefined = ar.currentline = -1;
     ar.source          = "=(tail call)";
     LinyeeOChunkID(ar.short_src, ar.source, LINYEE_IDSIZE);
     ar.nups = 0;
 }
Пример #7
0
        public static CharPtr LinyeeGetLocal(LinyeeState L, LinyeeDebug ar, int n)
        {
            CallInfo ci   = L.base_ci[ar.i_ci];
            CharPtr  name = FindLocal(L, ci, n);

            LinyeeLock(L);
            if (name != null)
            {
                LinyeeAPushObject(L, ci.base_[n - 1]);
            }
            LinyeeUnlock(L);
            return(name);
        }
Пример #8
0
        public static CharPtr LinyeeSetLocal(LinyeeState L, LinyeeDebug ar, int n)
        {
            CallInfo ci   = L.base_ci[ar.i_ci];
            CharPtr  name = FindLocal(L, ci, n);

            LinyeeLock(L);
            if (name != null)
            {
                SetObj2S(L, ci.base_[n - 1], L.top - 1);
            }
            StkId.Dec(ref L.top);        /* pop value */
            LinyeeUnlock(L);
            return(name);
        }
Пример #9
0
        public static void LinyeeLWhere(LinyeeState L, int level)
        {
            LinyeeDebug ar = new LinyeeDebug();

            if (LinyeeGetStack(L, level, ref ar) != 0) /* check function at level */
            {
                LinyeeGetInfo(L, "Sl", ref ar);        /* get info about it */
                if (ar.currentline > 0)                /* is there info? */
                {
                    LinyeePushFString(L, "%s:%d: ", ar.short_src, ar.currentline);
                    return;
                }
            }
            LinyeePushLiteral(L, "");        /* else, no information available... */
        }
Пример #10
0
        private static int AuxGetInfo(LinyeeState L, CharPtr what, LinyeeDebug ar,
                                      Closure f, CallInfo ci)
        {
            int status = 1;

            if (f == null)
            {
                InfoTailCall(ar);
                return(status);
            }
            for (; what[0] != 0; what = what.next())
            {
                switch (what[0])
                {
                case 'S': {
                    FuncInfo(ar, f);
                    break;
                }

                case 'l': {
                    ar.currentline = (ci != null) ? CurrentLine(L, ci) : -1;
                    break;
                }

                case 'u': {
                    ar.nups = f.c.nupvalues;
                    break;
                }

                case 'n': {
                    ar.namewhat = (ci != null) ? GetFuncName(L, ci, ref ar.name) : null;
                    if (ar.namewhat == null)
                    {
                        ar.namewhat = "";            /* not found */
                        ar.name     = null;
                    }
                    break;
                }

                case 'L':
                case 'f':            /* handled by ly_getinfo */
                    break;

                default: status = 0;  break;          /* invalid option */
                }
            }
            return(status);
        }
Пример #11
0
        private static int DBSetLocal(LinyeeState L)
        {
            int         arg;
            LinyeeState L1 = GetThread(L, out arg);
            LinyeeDebug ar = new LinyeeDebug();

            if (LinyeeGetStack(L1, LinyeeLCheckInt(L, arg + 1), ref ar) == 0)    /* out of range? */
            {
                return(LinyeeLArgError(L, arg + 1, "level out of range"));
            }
            LinyeeLCheckAny(L, arg + 3);
            LinyeeSetTop(L, arg + 3);
            LinyeeXMove(L, L1, 1);
            LinyeePushString(L, LinyeeSetLocal(L1, ar, LinyeeLCheckInt(L, arg + 2)));
            return(1);
        }
Пример #12
0
 private static void FuncInfo(LinyeeDebug ar, Closure cl)
 {
     if (cl.c.isC != 0)
     {
         ar.source          = "=[C]";
         ar.linedefined     = -1;
         ar.lastlinedefined = -1;
         ar.what            = "C";
     }
     else
     {
         ar.source          = GetStr(cl.l.p.source);
         ar.linedefined     = cl.l.p.linedefined;
         ar.lastlinedefined = cl.l.p.lastlinedefined;
         ar.what            = (ar.linedefined == 0) ? "main" : "Linyee";
     }
     LinyeeOChunkID(ar.short_src, ar.source, LINYEE_IDSIZE);
 }
Пример #13
0
        public static int LinyeeGetInfo(LinyeeState L, CharPtr what, ref LinyeeDebug ar)
        {
            int      status;
            Closure  f  = null;
            CallInfo ci = null;

            LinyeeLock(L);
            if (what == '>')
            {
                StkId func = L.top - 1;
                luai_apicheck(L, TTIsFunction(func));
                what = what.next();         /* skip the '>' */
                f    = CLValue(func);
                StkId.Dec(ref L.top);       /* pop function */
            }
            else if (ar.i_ci != 0)          /* no tail call? */
            {
                ci = L.base_ci[ar.i_ci];
                LinyeeAssert(TTIsFunction(ci.func));
                f = CLValue(ci.func);
            }
            status = AuxGetInfo(L, what, ar, f, ci);
            if (strchr(what, 'f') != null)
            {
                if (f == null)
                {
                    SetNilValue(L.top);
                }
                else
                {
                    SetCLValue(L, L.top, f);
                }
                IncrTop(L);
            }
            if (strchr(what, 'L') != null)
            {
                CollectValidLines(L, f);
            }
            LinyeeUnlock(L);
            return(status);
        }
Пример #14
0
 private static void HookF(LinyeeState L, LinyeeDebug ar)
 {
     LinyeePushLightUserData(L, KEY_HOOK);
     LinyeeRawGet(L, LINYEE_REGISTRYINDEX);
     LinyeePushLightUserData(L, L);
     LinyeeRawGet(L, -2);
     if (LinyeeIsFunction(L, -1))
     {
         LinyeePushString(L, hooknames[(int)ar.event_]);
         if (ar.currentline >= 0)
         {
             LinyeePushInteger(L, ar.currentline);
         }
         else
         {
             LinyeePushNil(L);
         }
         LinyeeAssert(LinyeeGetInfo(L, "lS", ref ar));
         LinyeeCall(L, 2, 0);
     }
 }
Пример #15
0
 private static void GetFunc(LinyeeState L, int opt)
 {
     if (LinyeeIsFunction(L, 1))
     {
         LinyeePushValue(L, 1);
     }
     else
     {
         LinyeeDebug ar    = new LinyeeDebug();
         int         level = (opt != 0) ? LinyeeLOptInt(L, 1, 1) : LinyeeLCheckInt(L, 1);
         LinyeeLArgCheck(L, level >= 0, 1, "level must be non-negative");
         if (LinyeeGetStack(L, level, ref ar) == 0)
         {
             LinyeeLArgError(L, 1, "invalid level");
         }
         LinyeeGetInfo(L, "f", ref ar);
         if (LinyeeIsNil(L, -1))
         {
             LinyeeLError(L, "no function environment for tail call at level %d",
                          level);
         }
     }
 }
Пример #16
0
 static void lstop(LinyeeState L, LinyeeDebug ar)
 {
     Linyee.LinyeeSetHook(L, null, 0, 0);
     Linyee.LinyeeLError(L, $"{Resource.interrupted}{Resource.Keyboard21}");
 }
Пример #17
0
        public const int LEVELS2 = 10;                  /* size of the second part of the stack */

        private static int DBErrorFB(LinyeeState L)
        {
            int         level;
            bool        firstpart = true; /* still before eventual `...' */
            int         arg;
            LinyeeState L1 = GetThread(L, out arg);
            LinyeeDebug ar = new LinyeeDebug();

            if (LinyeeIsNumber(L, arg + 2) != 0)
            {
                level = (int)LinyeeToInteger(L, arg + 2);
                LinyeePop(L, 1);
            }
            else
            {
                level = (L == L1) ? 1 : 0;          /* level 0 may be this own function */
            }
            if (LinyeeGetTop(L) == arg)
            {
                LinyeePushLiteral(L, "");
            }
            else if (LinyeeIsString(L, arg + 1) == 0)
            {
                return(1);                                         /* message is not a string */
            }
            else
            {
                LinyeePushLiteral(L, "\n");
            }
            LinyeePushLiteral(L, "stack traceback:");
            while (LinyeeGetStack(L1, level++, ref ar) != 0)
            {
                if (level > LEVELS1 && firstpart)
                {
                    /* no more than `LEVELS2' more levels? */
                    if (LinyeeGetStack(L1, level + LEVELS2, ref ar) == 0)
                    {
                        level--;          /* keep going */
                    }
                    else
                    {
                        LinyeePushLiteral(L, "\n\t...");                         /* too many levels */
                        while (LinyeeGetStack(L1, level + LEVELS2, ref ar) != 0) /* find last levels */
                        {
                            level++;
                        }
                    }
                    firstpart = false;
                    continue;
                }
                LinyeePushLiteral(L, "\n\t");
                LinyeeGetInfo(L1, "Snl", ref ar);
                LinyeePushFString(L, "%s:", ar.short_src);
                if (ar.currentline > 0)
                {
                    LinyeePushFString(L, "%d:", ar.currentline);
                }
                if (ar.namewhat != '\0')          /* is there a name? */
                {
                    LinyeePushFString(L, " in function " + LINYEE_QS, ar.name);
                }
                else
                {
                    if (ar.what == 'm')        /* main? */
                    {
                        LinyeePushFString(L, " in main chunk");
                    }
                    else if (ar.what == 'C' || ar.what == 't')
                    {
                        LinyeePushLiteral(L, " ?");          /* C function or tail call */
                    }
                    else
                    {
                        LinyeePushFString(L, " in function <%s:%d>",
                                          ar.short_src, ar.linedefined);
                    }
                }
                LinyeeConcat(L, LinyeeGetTop(L) - arg);
            }
            LinyeeConcat(L, LinyeeGetTop(L) - arg);
            return(1);
        }
Пример #18
0
        private static int DBGetInfo(LinyeeState L)
        {
            LinyeeDebug ar = new LinyeeDebug();
            int         arg;
            LinyeeState L1      = GetThread(L, out arg);
            CharPtr     options = LinyeeLOptString(L, arg + 2, "flnSu");

            if (LinyeeIsNumber(L, arg + 1) != 0)
            {
                if (LinyeeGetStack(L1, (int)LinyeeToInteger(L, arg + 1), ref ar) == 0)
                {
                    LinyeePushNil(L);        /* level out of range */
                    return(1);
                }
            }
            else if (LinyeeIsFunction(L, arg + 1))
            {
                LinyeePushFString(L, ">%s", options);
                options = LinyeeToString(L, -1);
                LinyeePushValue(L, arg + 1);
                LinyeeXMove(L, L1, 1);
            }
            else
            {
                return(LinyeeLArgError(L, arg + 1, "function or level expected"));
            }
            if (LinyeeGetInfo(L1, options, ref ar) == 0)
            {
                return(LinyeeLArgError(L, arg + 2, "invalid option"));
            }
            LinyeeCreateTable(L, 0, 2);
            if (strchr(options, 'S') != null)
            {
                SetTabsS(L, "source", ar.source);
                SetTabsS(L, "short_src", ar.short_src);
                SetTabSI(L, "linedefined", ar.linedefined);
                SetTabSI(L, "lastlinedefined", ar.lastlinedefined);
                SetTabsS(L, "what", ar.what);
            }
            if (strchr(options, 'l') != null)
            {
                SetTabSI(L, "currentline", ar.currentline);
            }
            if (strchr(options, 'u') != null)
            {
                SetTabSI(L, "nups", ar.nups);
            }
            if (strchr(options, 'n') != null)
            {
                SetTabsS(L, "name", ar.name);
                SetTabsS(L, "namewhat", ar.namewhat);
            }
            if (strchr(options, 'L') != null)
            {
                TreatStackOption(L, L1, "activelines");
            }
            if (strchr(options, 'f') != null)
            {
                TreatStackOption(L, L1, "func");
            }
            return(1);       /* return table */
        }