📄 lcode.c
字号:
} e->f = e->t = NO_JUMP; e->info = reg; e->k = VNONRELOC;}void luaK_exp2nextreg (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); freeexp(fs, e); luaK_reserveregs(fs, 1); luaK_exp2reg(fs, e, fs->freereg - 1);}int luaK_exp2anyreg (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); if (e->k == VNONRELOC) { if (!hasjumps(e)) return e->info; /* exp is already in a register */ if (e->info >= fs->nactvar) { /* reg. is not a local? */ luaK_exp2reg(fs, e, e->info); /* put value on it */ return e->info; } } luaK_exp2nextreg(fs, e); /* default */ return e->info;}void luaK_exp2val (FuncState *fs, expdesc *e) { if (hasjumps(e)) luaK_exp2anyreg(fs, e); else luaK_dischargevars(fs, e);}int luaK_exp2RK (FuncState *fs, expdesc *e) { luaK_exp2val(fs, e); switch (e->k) { case VNIL: { if (fs->nk + MAXSTACK <= MAXARG_C) { /* constant fit in argC? */ e->info = nil_constant(fs); e->k = VK; return e->info + MAXSTACK; } else break; } case VK: { if (e->info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */ return e->info + MAXSTACK; else break; } default: break; } /* not a constant in the right range: put it in a register */ return luaK_exp2anyreg(fs, e);}void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) { switch (var->k) { case VLOCAL: { freeexp(fs, exp); luaK_exp2reg(fs, exp, var->info); return; } case VUPVAL: { int e = luaK_exp2anyreg(fs, exp); luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0); break; } case VGLOBAL: { int e = luaK_exp2anyreg(fs, exp); luaK_codeABx(fs, OP_SETGLOBAL, e, var->info); break; } case VINDEXED: { int e = luaK_exp2RK(fs, exp); luaK_codeABC(fs, OP_SETTABLE, var->info, var->aux, e); break; } default: { lua_assert(0); /* invalid var kind to store */ break; } } freeexp(fs, exp);}void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { int func; luaK_exp2anyreg(fs, e); freeexp(fs, e); func = fs->freereg; luaK_reserveregs(fs, 2); luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key)); freeexp(fs, key); e->info = func; e->k = VNONRELOC;}static void invertjump (FuncState *fs, expdesc *e) { Instruction *pc = getjumpcontrol(fs, e->info); lua_assert(testOpMode(GET_OPCODE(*pc), OpModeT) && GET_OPCODE(*pc) != OP_TEST); SETARG_A(*pc, !(GETARG_A(*pc)));}static int jumponcond (FuncState *fs, expdesc *e, int cond) { if (e->k == VRELOCABLE) { Instruction ie = getcode(fs, e); if (GET_OPCODE(ie) == OP_NOT) { fs->pc--; /* remove previous OP_NOT */ return luaK_condjump(fs, OP_TEST, NO_REG, GETARG_B(ie), !cond); } /* else go through */ } discharge2anyreg(fs, e); freeexp(fs, e); return luaK_condjump(fs, OP_TEST, NO_REG, e->info, cond);}void luaK_goiftrue (FuncState *fs, expdesc *e) { int pc; /* pc of last jump */ luaK_dischargevars(fs, e); switch (e->k) { case VK: case VTRUE: { pc = NO_JUMP; /* always true; do nothing */ break; } case VFALSE: { pc = luaK_jump(fs); /* always jump */ break; } case VJMP: { invertjump(fs, e); pc = e->info; break; } default: { pc = jumponcond(fs, e, 0); break; } } luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */}void luaK_goiffalse (FuncState *fs, expdesc *e) { int pc; /* pc of last jump */ luaK_dischargevars(fs, e); switch (e->k) { case VNIL: case VFALSE: { pc = NO_JUMP; /* always false; do nothing */ break; } case VTRUE: { pc = luaK_jump(fs); /* always jump */ break; } case VJMP: { pc = e->info; break; } default: { pc = jumponcond(fs, e, 1); break; } } luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */}static void codenot (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); switch (e->k) { case VNIL: case VFALSE: { e->k = VTRUE; break; } case VK: case VTRUE: { e->k = VFALSE; break; } case VJMP: { invertjump(fs, e); break; } case VRELOCABLE: case VNONRELOC: { discharge2anyreg(fs, e); freeexp(fs, e); e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0); e->k = VRELOCABLE; break; } default: { lua_assert(0); /* cannot happen */ break; } } /* interchange true and false lists */ { int temp = e->f; e->f = e->t; e->t = temp; }}void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { t->aux = luaK_exp2RK(fs, k); t->k = VINDEXED;}void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { if (op == OPR_MINUS) { luaK_exp2val(fs, e); if (e->k == VK && ttisnumber(&fs->f->k[e->info])) e->info = luaK_numberK(fs, -nvalue(&fs->f->k[e->info])); else { luaK_exp2anyreg(fs, e); freeexp(fs, e); e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0); e->k = VRELOCABLE; } } else /* op == NOT */ codenot(fs, e);}void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { switch (op) { case OPR_AND: { luaK_goiftrue(fs, v); luaK_patchtohere(fs, v->t); v->t = NO_JUMP; break; } case OPR_OR: { luaK_goiffalse(fs, v); luaK_patchtohere(fs, v->f); v->f = NO_JUMP; break; } case OPR_CONCAT: { luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ break; } default: { luaK_exp2RK(fs, v); break; } }}static void codebinop (FuncState *fs, expdesc *res, BinOpr op, int o1, int o2) { if (op <= OPR_POW) { /* arithmetic operator? */ OpCode opc = cast(OpCode, (op - OPR_ADD) + OP_ADD); /* ORDER OP */ res->info = luaK_codeABC(fs, opc, 0, o1, o2); res->k = VRELOCABLE; } else { /* test operator */ static const OpCode ops[] = {OP_EQ, OP_EQ, OP_LT, OP_LE, OP_LT, OP_LE}; int cond = 1; if (op >= OPR_GT) { /* `>' or `>='? */ int temp; /* exchange args and replace by `<' or `<=' */ temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ } else if (op == OPR_NE) cond = 0; res->info = luaK_condjump(fs, ops[op - OPR_NE], cond, o1, o2); res->k = VJMP; }}void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { switch (op) { case OPR_AND: { lua_assert(e1->t == NO_JUMP); /* list must be closed */ luaK_dischargevars(fs, e2); luaK_concat(fs, &e1->f, e2->f); e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t; break; } case OPR_OR: { lua_assert(e1->f == NO_JUMP); /* list must be closed */ luaK_dischargevars(fs, e2); luaK_concat(fs, &e1->t, e2->t); e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f; break; } case OPR_CONCAT: { luaK_exp2val(fs, e2); if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1); freeexp(fs, e1); SETARG_B(getcode(fs, e2), e1->info); e1->k = e2->k; e1->info = e2->info; } else { luaK_exp2nextreg(fs, e2); freeexp(fs, e2); freeexp(fs, e1); e1->info = luaK_codeABC(fs, OP_CONCAT, 0, e1->info, e2->info); e1->k = VRELOCABLE; } break; } default: { int o1 = luaK_exp2RK(fs, e1); int o2 = luaK_exp2RK(fs, e2); freeexp(fs, e2); freeexp(fs, e1); codebinop(fs, e1, op, o1, o2); } }}void luaK_fixline (FuncState *fs, int line) { fs->f->lineinfo[fs->pc - 1] = line;}int luaK_code (FuncState *fs, Instruction i, int line) { Proto *f = fs->f; luaK_dischargejpc(fs); /* `pc' will change */ /* put new instruction in code array */ luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, MAX_INT, "code size overflow"); f->code[fs->pc] = i; /* save corresponding line information */ luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, MAX_INT, "code size overflow"); f->lineinfo[fs->pc] = line; return fs->pc++;}int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { lua_assert(getOpMode(o) == iABC); return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);}int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -