⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lvm.c

📁 世界上最快的脚本语言lua的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#define dojump(pc, i)	((pc) += (i))StkId luaV_execute (lua_State *L) {  LClosure *cl;  TObject *k;  const Instruction *pc; callentry:  /* entry point when calling new functions */  if (L->hookmask & LUA_MASKCALL) {    L->ci->u.l.pc = &pc;    luaD_callhook(L, LUA_HOOKCALL, -1);  } retentry:  /* entry point when returning to old functions */  L->ci->u.l.pc = &pc;  lua_assert(L->ci->state == CI_SAVEDPC ||             L->ci->state == (CI_SAVEDPC | CI_CALLING));  L->ci->state = CI_HASFRAME;  /* activate frame */  pc = L->ci->u.l.savedpc;  cl = &clvalue(L->base - 1)->l;  k = cl->p->k;  /* main loop of interpreter */  for (;;) {    const Instruction i = *pc++;    StkId base, ra;    if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&        (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {      traceexec(L);      if (L->ci->state & CI_YIELD) {  /* did hook yield? */        L->ci->u.l.savedpc = pc - 1;        L->ci->state = CI_YIELD | CI_SAVEDPC;        return NULL;      }    }    /* warning!! several calls may realloc the stack and invalidate `ra' */    base = L->base;    ra = RA(i);    lua_assert(L->ci->state & CI_HASFRAME);    lua_assert(base == L->ci->base);    lua_assert(L->top <= L->stack + L->stacksize && L->top >= base);    lua_assert(L->top == L->ci->top ||         GET_OPCODE(i) == OP_CALL ||   GET_OPCODE(i) == OP_TAILCALL ||         GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO);    switch (GET_OPCODE(i)) {      case OP_MOVE: {        setobjs2s(ra, RB(i));        break;      }      case OP_LOADK: {        setobj2s(ra, KBx(i));        break;      }      case OP_LOADBOOL: {        setbvalue(ra, GETARG_B(i));        if (GETARG_C(i)) pc++;  /* skip next instruction (if C) */        break;      }      case OP_LOADNIL: {        TObject *rb = RB(i);        do {          setnilvalue(rb--);        } while (rb >= ra);        break;      }      case OP_GETUPVAL: {        int b = GETARG_B(i);        setobj2s(ra, cl->upvals[b]->v);        break;      }      case OP_GETGLOBAL: {        TObject *rb = KBx(i);        const TObject *v;        lua_assert(ttisstring(rb) && ttistable(&cl->g));        v = luaH_getstr(hvalue(&cl->g), tsvalue(rb));        if (!ttisnil(v)) { setobj2s(ra, v); }        else          setobj2s(XRA(i), luaV_index(L, &cl->g, rb, 0));        break;      }      case OP_GETTABLE: {        StkId rb = RB(i);        TObject *rc = RKC(i);        if (ttistable(rb)) {          const TObject *v = luaH_get(hvalue(rb), rc);          if (!ttisnil(v)) { setobj2s(ra, v); }          else            setobj2s(XRA(i), luaV_index(L, rb, rc, 0));        }        else          setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0));        break;      }      case OP_SETGLOBAL: {        lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));        luaV_settable(L, &cl->g, KBx(i), ra);        break;      }      case OP_SETUPVAL: {        int b = GETARG_B(i);        setobj(cl->upvals[b]->v, ra);  /* write barrier */        break;      }      case OP_SETTABLE: {        luaV_settable(L, ra, RKB(i), RKC(i));        break;      }      case OP_NEWTABLE: {        int b = GETARG_B(i);        b = fb2int(b);        sethvalue(ra, luaH_new(L, b, GETARG_C(i)));        luaC_checkGC(L);        break;      }      case OP_SELF: {        StkId rb = RB(i);        TObject *rc = RKC(i);        runtime_check(L, ttisstring(rc));        setobjs2s(ra+1, rb);        if (ttistable(rb)) {          const TObject *v = luaH_getstr(hvalue(rb), tsvalue(rc));          if (!ttisnil(v)) { setobj2s(ra, v); }          else            setobj2s(XRA(i), luaV_index(L, rb, rc, 0));        }        else          setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0));        break;      }      case OP_ADD: {        TObject *rb = RKB(i);        TObject *rc = RKC(i);        if (ttisnumber(rb) && ttisnumber(rc)) {          setnvalue(ra, nvalue(rb) + nvalue(rc));        }        else          Arith(L, ra, rb, rc, TM_ADD);        break;      }      case OP_SUB: {        TObject *rb = RKB(i);        TObject *rc = RKC(i);        if (ttisnumber(rb) && ttisnumber(rc)) {          setnvalue(ra, nvalue(rb) - nvalue(rc));        }        else          Arith(L, ra, rb, rc, TM_SUB);        break;      }      case OP_MUL: {        TObject *rb = RKB(i);        TObject *rc = RKC(i);        if (ttisnumber(rb) && ttisnumber(rc)) {          setnvalue(ra, nvalue(rb) * nvalue(rc));        }        else          Arith(L, ra, rb, rc, TM_MUL);        break;      }      case OP_DIV: {        TObject *rb = RKB(i);        TObject *rc = RKC(i);        if (ttisnumber(rb) && ttisnumber(rc)) {          setnvalue(ra, nvalue(rb) / nvalue(rc));        }        else          Arith(L, ra, rb, rc, TM_DIV);        break;      }      case OP_POW: {        Arith(L, ra, RKB(i), RKC(i), TM_POW);        break;      }      case OP_UNM: {        const TObject *rb = RB(i);        TObject temp;        if (tonumber(rb, &temp)) {          setnvalue(ra, -nvalue(rb));        }        else {          setnilvalue(&temp);          if (!call_binTM(L, RB(i), &temp, ra, TM_UNM))            luaG_aritherror(L, RB(i), &temp);        }        break;      }      case OP_NOT: {        int res = l_isfalse(RB(i));  /* next assignment may change this value */        setbvalue(ra, res);        break;      }      case OP_CONCAT: {        int b = GETARG_B(i);        int c = GETARG_C(i);        luaV_concat(L, c-b+1, c);  /* may change `base' (and `ra') */        base = L->base;        setobjs2s(RA(i), base+b);        luaC_checkGC(L);        break;      }      case OP_JMP: {        dojump(pc, GETARG_sBx(i));        break;      }      case OP_EQ: {        if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;        else dojump(pc, GETARG_sBx(*pc) + 1);        break;      }      case OP_LT: {        if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;        else dojump(pc, GETARG_sBx(*pc) + 1);        break;      }      case OP_LE: {        if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;        else dojump(pc, GETARG_sBx(*pc) + 1);        break;      }      case OP_TEST: {        TObject *rb = RB(i);        if (l_isfalse(rb) == GETARG_C(i)) pc++;        else {          setobjs2s(ra, rb);          dojump(pc, GETARG_sBx(*pc) + 1);        }        break;      }      case OP_CALL:      case OP_TAILCALL: {        StkId firstResult;        int b = GETARG_B(i);        int nresults;        if (b != 0) L->top = ra+b;  /* else previous instruction set top */        nresults = GETARG_C(i) - 1;        firstResult = luaD_precall(L, ra);        if (firstResult) {          if (firstResult > L->top) {  /* yield? */            lua_assert(L->ci->state == (CI_C | CI_YIELD));            (L->ci - 1)->u.l.savedpc = pc;            (L->ci - 1)->state = CI_SAVEDPC;            return NULL;          }          /* it was a C function (`precall' called it); adjust results */          luaD_poscall(L, nresults, firstResult);          if (nresults >= 0) L->top = L->ci->top;        }        else {  /* it is a Lua function */          if (GET_OPCODE(i) == OP_CALL) {  /* regular call? */            (L->ci-1)->u.l.savedpc = pc;  /* save `pc' to return later */            (L->ci-1)->state = (CI_SAVEDPC | CI_CALLING);          }          else {  /* tail call: put new frame in place of previous one */            int aux;            base = (L->ci - 1)->base;  /* `luaD_precall' may change the stack */            ra = RA(i);            if (L->openupval) luaF_close(L, base);            for (aux = 0; ra+aux < L->top; aux++)  /* move frame down */              setobjs2s(base+aux-1, ra+aux);            (L->ci - 1)->top = L->top = base+aux;  /* correct top */            lua_assert(L->ci->state & CI_SAVEDPC);            (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;            (L->ci - 1)->u.l.tailcalls++;  /* one more call lost */            (L->ci - 1)->state = CI_SAVEDPC;            L->ci--;  /* remove new frame */            L->base = L->ci->base;          }          goto callentry;        }        break;      }      case OP_RETURN: {        CallInfo *ci = L->ci - 1;  /* previous function frame */        int b = GETARG_B(i);        if (b != 0) L->top = ra+b-1;        lua_assert(L->ci->state & CI_HASFRAME);        if (L->openupval) luaF_close(L, base);        L->ci->state = CI_SAVEDPC;  /* deactivate current function */        L->ci->u.l.savedpc = pc;        /* previous function was running `here'? */        if (!(ci->state & CI_CALLING)) {          lua_assert((ci->state & CI_C) || ci->u.l.pc != &pc);          return ra;  /* no: return */        }        else {  /* yes: continue its execution */          int nresults;          lua_assert(ttisfunction(ci->base - 1) && (ci->state & CI_SAVEDPC));          lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);          nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;          luaD_poscall(L, nresults, ra);          if (nresults >= 0) L->top = L->ci->top;          goto retentry;        }      }      case OP_FORLOOP: {        lua_Number step, idx, limit;        const TObject *plimit = ra+1;        const TObject *pstep = ra+2;        if (!ttisnumber(ra))          luaG_runerror(L, "`for' initial value must be a number");        if (!tonumber(plimit, ra+1))          luaG_runerror(L, "`for' limit must be a number");        if (!tonumber(pstep, ra+2))          luaG_runerror(L, "`for' step must be a number");        step = nvalue(pstep);        idx = nvalue(ra) + step;  /* increment index */        limit = nvalue(plimit);        if (step > 0 ? idx <= limit : idx >= limit) {          dojump(pc, GETARG_sBx(i));  /* jump back */          chgnvalue(ra, idx);  /* update index */        }        break;      }      case OP_TFORLOOP: {        int nvar = GETARG_C(i) + 1;        StkId cb = ra + nvar + 2;  /* call base */        setobjs2s(cb, ra);        setobjs2s(cb+1, ra+1);        setobjs2s(cb+2, ra+2);        L->top = cb+3;  /* func. + 2 args (state and index) */        luaD_call(L, cb, nvar);        L->top = L->ci->top;        ra = XRA(i) + 2;  /* final position of first result */        cb = ra + nvar;        do {  /* move results to proper positions */          nvar--;          setobjs2s(ra+nvar, cb+nvar);        } while (nvar > 0);        if (ttisnil(ra))  /* break loop? */          pc++;  /* skip jump (break loop) */        else          dojump(pc, GETARG_sBx(*pc) + 1);  /* jump back */        break;      }      case OP_TFORPREP: {  /* for compatibility only */        if (ttistable(ra)) {          setobjs2s(ra+1, ra);          setobj2s(ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next")));        }        dojump(pc, GETARG_sBx(i));        break;      }      case OP_SETLIST:      case OP_SETLISTO: {        int bc;        int n;        Table *h;        runtime_check(L, ttistable(ra));        h = hvalue(ra);        bc = GETARG_Bx(i);        if (GET_OPCODE(i) == OP_SETLIST)          n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;        else {          n = L->top - ra - 1;          L->top = L->ci->top;        }        bc &= ~(LFIELDS_PER_FLUSH-1);  /* bc = bc - bc%FPF */        for (; n > 0; n--)          setobj2t(luaH_setnum(L, h, bc+n), ra+n);  /* write barrier */        break;      }      case OP_CLOSE: {        luaF_close(L, ra);        break;      }      case OP_CLOSURE: {        Proto *p;        Closure *ncl;        int nup, j;        p = cl->p->p[GETARG_Bx(i)];        nup = p->nups;        ncl = luaF_newLclosure(L, nup, &cl->g);        ncl->l.p = p;        for (j=0; j<nup; j++, pc++) {          if (GET_OPCODE(*pc) == OP_GETUPVAL)            ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];          else {            lua_assert(GET_OPCODE(*pc) == OP_MOVE);            ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));          }        }        setclvalue(ra, ncl);        luaC_checkGC(L);        break;      }    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -