116a5fed65808adf648004b34f98718301d718fa2darylm/* 216a5fed65808adf648004b34f98718301d718fa2darylm** $Id: lcode.c,v 2.62.1.1 2013/04/12 18:48:47 roberto Exp $ 316a5fed65808adf648004b34f98718301d718fa2darylm** Code generator for Lua 416a5fed65808adf648004b34f98718301d718fa2darylm** See Copyright Notice in lua.h 516a5fed65808adf648004b34f98718301d718fa2darylm*/ 616a5fed65808adf648004b34f98718301d718fa2darylm 716a5fed65808adf648004b34f98718301d718fa2darylm 816a5fed65808adf648004b34f98718301d718fa2darylm#include <stdlib.h> 916a5fed65808adf648004b34f98718301d718fa2darylm 1016a5fed65808adf648004b34f98718301d718fa2darylm#define lcode_c 1116a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_CORE 1216a5fed65808adf648004b34f98718301d718fa2darylm 1316a5fed65808adf648004b34f98718301d718fa2darylm#include "lua.h" 1416a5fed65808adf648004b34f98718301d718fa2darylm 1516a5fed65808adf648004b34f98718301d718fa2darylm#include "lcode.h" 1616a5fed65808adf648004b34f98718301d718fa2darylm#include "ldebug.h" 1716a5fed65808adf648004b34f98718301d718fa2darylm#include "ldo.h" 1816a5fed65808adf648004b34f98718301d718fa2darylm#include "lgc.h" 1916a5fed65808adf648004b34f98718301d718fa2darylm#include "llex.h" 2016a5fed65808adf648004b34f98718301d718fa2darylm#include "lmem.h" 2116a5fed65808adf648004b34f98718301d718fa2darylm#include "lobject.h" 2216a5fed65808adf648004b34f98718301d718fa2darylm#include "lopcodes.h" 2316a5fed65808adf648004b34f98718301d718fa2darylm#include "lparser.h" 2416a5fed65808adf648004b34f98718301d718fa2darylm#include "lstring.h" 2516a5fed65808adf648004b34f98718301d718fa2darylm#include "ltable.h" 2616a5fed65808adf648004b34f98718301d718fa2darylm#include "lvm.h" 2716a5fed65808adf648004b34f98718301d718fa2darylm 2816a5fed65808adf648004b34f98718301d718fa2darylm 2916a5fed65808adf648004b34f98718301d718fa2darylm#define hasjumps(e) ((e)->t != (e)->f) 3016a5fed65808adf648004b34f98718301d718fa2darylm 3116a5fed65808adf648004b34f98718301d718fa2darylm 3216a5fed65808adf648004b34f98718301d718fa2darylmstatic int isnumeral(expdesc *e) { 3316a5fed65808adf648004b34f98718301d718fa2darylm return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); 3416a5fed65808adf648004b34f98718301d718fa2darylm} 3516a5fed65808adf648004b34f98718301d718fa2darylm 3616a5fed65808adf648004b34f98718301d718fa2darylm 3716a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_nil (FuncState *fs, int from, int n) { 3816a5fed65808adf648004b34f98718301d718fa2darylm Instruction *previous; 3916a5fed65808adf648004b34f98718301d718fa2darylm int l = from + n - 1; /* last register to set nil */ 4016a5fed65808adf648004b34f98718301d718fa2darylm if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ 4116a5fed65808adf648004b34f98718301d718fa2darylm previous = &fs->f->code[fs->pc-1]; 4216a5fed65808adf648004b34f98718301d718fa2darylm if (GET_OPCODE(*previous) == OP_LOADNIL) { 4316a5fed65808adf648004b34f98718301d718fa2darylm int pfrom = GETARG_A(*previous); 4416a5fed65808adf648004b34f98718301d718fa2darylm int pl = pfrom + GETARG_B(*previous); 4516a5fed65808adf648004b34f98718301d718fa2darylm if ((pfrom <= from && from <= pl + 1) || 4616a5fed65808adf648004b34f98718301d718fa2darylm (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ 4716a5fed65808adf648004b34f98718301d718fa2darylm if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ 4816a5fed65808adf648004b34f98718301d718fa2darylm if (pl > l) l = pl; /* l = max(l, pl) */ 4916a5fed65808adf648004b34f98718301d718fa2darylm SETARG_A(*previous, from); 5016a5fed65808adf648004b34f98718301d718fa2darylm SETARG_B(*previous, l - from); 5116a5fed65808adf648004b34f98718301d718fa2darylm return; 5216a5fed65808adf648004b34f98718301d718fa2darylm } 5316a5fed65808adf648004b34f98718301d718fa2darylm } /* else go through */ 5416a5fed65808adf648004b34f98718301d718fa2darylm } 5516a5fed65808adf648004b34f98718301d718fa2darylm luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ 5616a5fed65808adf648004b34f98718301d718fa2darylm} 5716a5fed65808adf648004b34f98718301d718fa2darylm 5816a5fed65808adf648004b34f98718301d718fa2darylm 5916a5fed65808adf648004b34f98718301d718fa2darylmint luaK_jump (FuncState *fs) { 6016a5fed65808adf648004b34f98718301d718fa2darylm int jpc = fs->jpc; /* save list of jumps to here */ 6116a5fed65808adf648004b34f98718301d718fa2darylm int j; 6216a5fed65808adf648004b34f98718301d718fa2darylm fs->jpc = NO_JUMP; 6316a5fed65808adf648004b34f98718301d718fa2darylm j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); 6416a5fed65808adf648004b34f98718301d718fa2darylm luaK_concat(fs, &j, jpc); /* keep them on hold */ 6516a5fed65808adf648004b34f98718301d718fa2darylm return j; 6616a5fed65808adf648004b34f98718301d718fa2darylm} 6716a5fed65808adf648004b34f98718301d718fa2darylm 6816a5fed65808adf648004b34f98718301d718fa2darylm 6916a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_ret (FuncState *fs, int first, int nret) { 7016a5fed65808adf648004b34f98718301d718fa2darylm luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); 7116a5fed65808adf648004b34f98718301d718fa2darylm} 7216a5fed65808adf648004b34f98718301d718fa2darylm 7316a5fed65808adf648004b34f98718301d718fa2darylm 7416a5fed65808adf648004b34f98718301d718fa2darylmstatic int condjump (FuncState *fs, OpCode op, int A, int B, int C) { 7516a5fed65808adf648004b34f98718301d718fa2darylm luaK_codeABC(fs, op, A, B, C); 7616a5fed65808adf648004b34f98718301d718fa2darylm return luaK_jump(fs); 7716a5fed65808adf648004b34f98718301d718fa2darylm} 7816a5fed65808adf648004b34f98718301d718fa2darylm 7916a5fed65808adf648004b34f98718301d718fa2darylm 8016a5fed65808adf648004b34f98718301d718fa2darylmstatic void fixjump (FuncState *fs, int pc, int dest) { 8116a5fed65808adf648004b34f98718301d718fa2darylm Instruction *jmp = &fs->f->code[pc]; 8216a5fed65808adf648004b34f98718301d718fa2darylm int offset = dest-(pc+1); 8316a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(dest != NO_JUMP); 8416a5fed65808adf648004b34f98718301d718fa2darylm if (abs(offset) > MAXARG_sBx) 8516a5fed65808adf648004b34f98718301d718fa2darylm luaX_syntaxerror(fs->ls, "control structure too long"); 8616a5fed65808adf648004b34f98718301d718fa2darylm SETARG_sBx(*jmp, offset); 8716a5fed65808adf648004b34f98718301d718fa2darylm} 8816a5fed65808adf648004b34f98718301d718fa2darylm 8916a5fed65808adf648004b34f98718301d718fa2darylm 9016a5fed65808adf648004b34f98718301d718fa2darylm/* 9116a5fed65808adf648004b34f98718301d718fa2darylm** returns current `pc' and marks it as a jump target (to avoid wrong 9216a5fed65808adf648004b34f98718301d718fa2darylm** optimizations with consecutive instructions not in the same basic block). 9316a5fed65808adf648004b34f98718301d718fa2darylm*/ 9416a5fed65808adf648004b34f98718301d718fa2darylmint luaK_getlabel (FuncState *fs) { 9516a5fed65808adf648004b34f98718301d718fa2darylm fs->lasttarget = fs->pc; 9616a5fed65808adf648004b34f98718301d718fa2darylm return fs->pc; 9716a5fed65808adf648004b34f98718301d718fa2darylm} 9816a5fed65808adf648004b34f98718301d718fa2darylm 9916a5fed65808adf648004b34f98718301d718fa2darylm 10016a5fed65808adf648004b34f98718301d718fa2darylmstatic int getjump (FuncState *fs, int pc) { 10116a5fed65808adf648004b34f98718301d718fa2darylm int offset = GETARG_sBx(fs->f->code[pc]); 10216a5fed65808adf648004b34f98718301d718fa2darylm if (offset == NO_JUMP) /* point to itself represents end of list */ 10316a5fed65808adf648004b34f98718301d718fa2darylm return NO_JUMP; /* end of list */ 10416a5fed65808adf648004b34f98718301d718fa2darylm else 10516a5fed65808adf648004b34f98718301d718fa2darylm return (pc+1)+offset; /* turn offset into absolute position */ 10616a5fed65808adf648004b34f98718301d718fa2darylm} 10716a5fed65808adf648004b34f98718301d718fa2darylm 10816a5fed65808adf648004b34f98718301d718fa2darylm 10916a5fed65808adf648004b34f98718301d718fa2darylmstatic Instruction *getjumpcontrol (FuncState *fs, int pc) { 11016a5fed65808adf648004b34f98718301d718fa2darylm Instruction *pi = &fs->f->code[pc]; 11116a5fed65808adf648004b34f98718301d718fa2darylm if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) 11216a5fed65808adf648004b34f98718301d718fa2darylm return pi-1; 11316a5fed65808adf648004b34f98718301d718fa2darylm else 11416a5fed65808adf648004b34f98718301d718fa2darylm return pi; 11516a5fed65808adf648004b34f98718301d718fa2darylm} 11616a5fed65808adf648004b34f98718301d718fa2darylm 11716a5fed65808adf648004b34f98718301d718fa2darylm 11816a5fed65808adf648004b34f98718301d718fa2darylm/* 11916a5fed65808adf648004b34f98718301d718fa2darylm** check whether list has any jump that do not produce a value 12016a5fed65808adf648004b34f98718301d718fa2darylm** (or produce an inverted value) 12116a5fed65808adf648004b34f98718301d718fa2darylm*/ 12216a5fed65808adf648004b34f98718301d718fa2darylmstatic int need_value (FuncState *fs, int list) { 12316a5fed65808adf648004b34f98718301d718fa2darylm for (; list != NO_JUMP; list = getjump(fs, list)) { 12416a5fed65808adf648004b34f98718301d718fa2darylm Instruction i = *getjumpcontrol(fs, list); 12516a5fed65808adf648004b34f98718301d718fa2darylm if (GET_OPCODE(i) != OP_TESTSET) return 1; 12616a5fed65808adf648004b34f98718301d718fa2darylm } 12716a5fed65808adf648004b34f98718301d718fa2darylm return 0; /* not found */ 12816a5fed65808adf648004b34f98718301d718fa2darylm} 12916a5fed65808adf648004b34f98718301d718fa2darylm 13016a5fed65808adf648004b34f98718301d718fa2darylm 13116a5fed65808adf648004b34f98718301d718fa2darylmstatic int patchtestreg (FuncState *fs, int node, int reg) { 13216a5fed65808adf648004b34f98718301d718fa2darylm Instruction *i = getjumpcontrol(fs, node); 13316a5fed65808adf648004b34f98718301d718fa2darylm if (GET_OPCODE(*i) != OP_TESTSET) 13416a5fed65808adf648004b34f98718301d718fa2darylm return 0; /* cannot patch other instructions */ 13516a5fed65808adf648004b34f98718301d718fa2darylm if (reg != NO_REG && reg != GETARG_B(*i)) 13616a5fed65808adf648004b34f98718301d718fa2darylm SETARG_A(*i, reg); 13716a5fed65808adf648004b34f98718301d718fa2darylm else /* no register to put value or register already has the value */ 13816a5fed65808adf648004b34f98718301d718fa2darylm *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); 13916a5fed65808adf648004b34f98718301d718fa2darylm 14016a5fed65808adf648004b34f98718301d718fa2darylm return 1; 14116a5fed65808adf648004b34f98718301d718fa2darylm} 14216a5fed65808adf648004b34f98718301d718fa2darylm 14316a5fed65808adf648004b34f98718301d718fa2darylm 14416a5fed65808adf648004b34f98718301d718fa2darylmstatic void removevalues (FuncState *fs, int list) { 14516a5fed65808adf648004b34f98718301d718fa2darylm for (; list != NO_JUMP; list = getjump(fs, list)) 14616a5fed65808adf648004b34f98718301d718fa2darylm patchtestreg(fs, list, NO_REG); 14716a5fed65808adf648004b34f98718301d718fa2darylm} 14816a5fed65808adf648004b34f98718301d718fa2darylm 14916a5fed65808adf648004b34f98718301d718fa2darylm 15016a5fed65808adf648004b34f98718301d718fa2darylmstatic void patchlistaux (FuncState *fs, int list, int vtarget, int reg, 15116a5fed65808adf648004b34f98718301d718fa2darylm int dtarget) { 15216a5fed65808adf648004b34f98718301d718fa2darylm while (list != NO_JUMP) { 15316a5fed65808adf648004b34f98718301d718fa2darylm int next = getjump(fs, list); 15416a5fed65808adf648004b34f98718301d718fa2darylm if (patchtestreg(fs, list, reg)) 15516a5fed65808adf648004b34f98718301d718fa2darylm fixjump(fs, list, vtarget); 15616a5fed65808adf648004b34f98718301d718fa2darylm else 15716a5fed65808adf648004b34f98718301d718fa2darylm fixjump(fs, list, dtarget); /* jump to default target */ 15816a5fed65808adf648004b34f98718301d718fa2darylm list = next; 15916a5fed65808adf648004b34f98718301d718fa2darylm } 16016a5fed65808adf648004b34f98718301d718fa2darylm} 16116a5fed65808adf648004b34f98718301d718fa2darylm 16216a5fed65808adf648004b34f98718301d718fa2darylm 16316a5fed65808adf648004b34f98718301d718fa2darylmstatic void dischargejpc (FuncState *fs) { 16416a5fed65808adf648004b34f98718301d718fa2darylm patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); 16516a5fed65808adf648004b34f98718301d718fa2darylm fs->jpc = NO_JUMP; 16616a5fed65808adf648004b34f98718301d718fa2darylm} 16716a5fed65808adf648004b34f98718301d718fa2darylm 16816a5fed65808adf648004b34f98718301d718fa2darylm 16916a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_patchlist (FuncState *fs, int list, int target) { 17016a5fed65808adf648004b34f98718301d718fa2darylm if (target == fs->pc) 17116a5fed65808adf648004b34f98718301d718fa2darylm luaK_patchtohere(fs, list); 17216a5fed65808adf648004b34f98718301d718fa2darylm else { 17316a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(target < fs->pc); 17416a5fed65808adf648004b34f98718301d718fa2darylm patchlistaux(fs, list, target, NO_REG, target); 17516a5fed65808adf648004b34f98718301d718fa2darylm } 17616a5fed65808adf648004b34f98718301d718fa2darylm} 17716a5fed65808adf648004b34f98718301d718fa2darylm 17816a5fed65808adf648004b34f98718301d718fa2darylm 17916a5fed65808adf648004b34f98718301d718fa2darylmLUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) { 18016a5fed65808adf648004b34f98718301d718fa2darylm level++; /* argument is +1 to reserve 0 as non-op */ 18116a5fed65808adf648004b34f98718301d718fa2darylm while (list != NO_JUMP) { 18216a5fed65808adf648004b34f98718301d718fa2darylm int next = getjump(fs, list); 18316a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && 18416a5fed65808adf648004b34f98718301d718fa2darylm (GETARG_A(fs->f->code[list]) == 0 || 18516a5fed65808adf648004b34f98718301d718fa2darylm GETARG_A(fs->f->code[list]) >= level)); 18616a5fed65808adf648004b34f98718301d718fa2darylm SETARG_A(fs->f->code[list], level); 18716a5fed65808adf648004b34f98718301d718fa2darylm list = next; 18816a5fed65808adf648004b34f98718301d718fa2darylm } 18916a5fed65808adf648004b34f98718301d718fa2darylm} 19016a5fed65808adf648004b34f98718301d718fa2darylm 19116a5fed65808adf648004b34f98718301d718fa2darylm 19216a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_patchtohere (FuncState *fs, int list) { 19316a5fed65808adf648004b34f98718301d718fa2darylm luaK_getlabel(fs); 19416a5fed65808adf648004b34f98718301d718fa2darylm luaK_concat(fs, &fs->jpc, list); 19516a5fed65808adf648004b34f98718301d718fa2darylm} 19616a5fed65808adf648004b34f98718301d718fa2darylm 19716a5fed65808adf648004b34f98718301d718fa2darylm 19816a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_concat (FuncState *fs, int *l1, int l2) { 19916a5fed65808adf648004b34f98718301d718fa2darylm if (l2 == NO_JUMP) return; 20016a5fed65808adf648004b34f98718301d718fa2darylm else if (*l1 == NO_JUMP) 20116a5fed65808adf648004b34f98718301d718fa2darylm *l1 = l2; 20216a5fed65808adf648004b34f98718301d718fa2darylm else { 20316a5fed65808adf648004b34f98718301d718fa2darylm int list = *l1; 20416a5fed65808adf648004b34f98718301d718fa2darylm int next; 20516a5fed65808adf648004b34f98718301d718fa2darylm while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ 20616a5fed65808adf648004b34f98718301d718fa2darylm list = next; 20716a5fed65808adf648004b34f98718301d718fa2darylm fixjump(fs, list, l2); 20816a5fed65808adf648004b34f98718301d718fa2darylm } 20916a5fed65808adf648004b34f98718301d718fa2darylm} 21016a5fed65808adf648004b34f98718301d718fa2darylm 21116a5fed65808adf648004b34f98718301d718fa2darylm 21216a5fed65808adf648004b34f98718301d718fa2darylmstatic int luaK_code (FuncState *fs, Instruction i) { 21316a5fed65808adf648004b34f98718301d718fa2darylm Proto *f = fs->f; 21416a5fed65808adf648004b34f98718301d718fa2darylm dischargejpc(fs); /* `pc' will change */ 21516a5fed65808adf648004b34f98718301d718fa2darylm /* put new instruction in code array */ 21616a5fed65808adf648004b34f98718301d718fa2darylm luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, 21716a5fed65808adf648004b34f98718301d718fa2darylm MAX_INT, "opcodes"); 21816a5fed65808adf648004b34f98718301d718fa2darylm f->code[fs->pc] = i; 21916a5fed65808adf648004b34f98718301d718fa2darylm /* save corresponding line information */ 22016a5fed65808adf648004b34f98718301d718fa2darylm luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int, 22116a5fed65808adf648004b34f98718301d718fa2darylm MAX_INT, "opcodes"); 22216a5fed65808adf648004b34f98718301d718fa2darylm f->lineinfo[fs->pc] = fs->ls->lastline; 22316a5fed65808adf648004b34f98718301d718fa2darylm return fs->pc++; 22416a5fed65808adf648004b34f98718301d718fa2darylm} 22516a5fed65808adf648004b34f98718301d718fa2darylm 22616a5fed65808adf648004b34f98718301d718fa2darylm 22716a5fed65808adf648004b34f98718301d718fa2darylmint luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { 22816a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(getOpMode(o) == iABC); 22916a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(getBMode(o) != OpArgN || b == 0); 23016a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(getCMode(o) != OpArgN || c == 0); 23116a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); 23216a5fed65808adf648004b34f98718301d718fa2darylm return luaK_code(fs, CREATE_ABC(o, a, b, c)); 23316a5fed65808adf648004b34f98718301d718fa2darylm} 23416a5fed65808adf648004b34f98718301d718fa2darylm 23516a5fed65808adf648004b34f98718301d718fa2darylm 23616a5fed65808adf648004b34f98718301d718fa2darylmint luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { 23716a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); 23816a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(getCMode(o) == OpArgN); 23916a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); 24016a5fed65808adf648004b34f98718301d718fa2darylm return luaK_code(fs, CREATE_ABx(o, a, bc)); 24116a5fed65808adf648004b34f98718301d718fa2darylm} 24216a5fed65808adf648004b34f98718301d718fa2darylm 24316a5fed65808adf648004b34f98718301d718fa2darylm 24416a5fed65808adf648004b34f98718301d718fa2darylmstatic int codeextraarg (FuncState *fs, int a) { 24516a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(a <= MAXARG_Ax); 24616a5fed65808adf648004b34f98718301d718fa2darylm return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); 24716a5fed65808adf648004b34f98718301d718fa2darylm} 24816a5fed65808adf648004b34f98718301d718fa2darylm 24916a5fed65808adf648004b34f98718301d718fa2darylm 25016a5fed65808adf648004b34f98718301d718fa2darylmint luaK_codek (FuncState *fs, int reg, int k) { 25116a5fed65808adf648004b34f98718301d718fa2darylm if (k <= MAXARG_Bx) 25216a5fed65808adf648004b34f98718301d718fa2darylm return luaK_codeABx(fs, OP_LOADK, reg, k); 25316a5fed65808adf648004b34f98718301d718fa2darylm else { 25416a5fed65808adf648004b34f98718301d718fa2darylm int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); 25516a5fed65808adf648004b34f98718301d718fa2darylm codeextraarg(fs, k); 25616a5fed65808adf648004b34f98718301d718fa2darylm return p; 25716a5fed65808adf648004b34f98718301d718fa2darylm } 25816a5fed65808adf648004b34f98718301d718fa2darylm} 25916a5fed65808adf648004b34f98718301d718fa2darylm 26016a5fed65808adf648004b34f98718301d718fa2darylm 26116a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_checkstack (FuncState *fs, int n) { 26216a5fed65808adf648004b34f98718301d718fa2darylm int newstack = fs->freereg + n; 26316a5fed65808adf648004b34f98718301d718fa2darylm if (newstack > fs->f->maxstacksize) { 26416a5fed65808adf648004b34f98718301d718fa2darylm if (newstack >= MAXSTACK) 26516a5fed65808adf648004b34f98718301d718fa2darylm luaX_syntaxerror(fs->ls, "function or expression too complex"); 26616a5fed65808adf648004b34f98718301d718fa2darylm fs->f->maxstacksize = cast_byte(newstack); 26716a5fed65808adf648004b34f98718301d718fa2darylm } 26816a5fed65808adf648004b34f98718301d718fa2darylm} 26916a5fed65808adf648004b34f98718301d718fa2darylm 27016a5fed65808adf648004b34f98718301d718fa2darylm 27116a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_reserveregs (FuncState *fs, int n) { 27216a5fed65808adf648004b34f98718301d718fa2darylm luaK_checkstack(fs, n); 27316a5fed65808adf648004b34f98718301d718fa2darylm fs->freereg += (lu_byte)n; 27416a5fed65808adf648004b34f98718301d718fa2darylm} 27516a5fed65808adf648004b34f98718301d718fa2darylm 27616a5fed65808adf648004b34f98718301d718fa2darylm 27716a5fed65808adf648004b34f98718301d718fa2darylmstatic void freereg (FuncState *fs, int reg) { 27816a5fed65808adf648004b34f98718301d718fa2darylm if (!ISK(reg) && reg >= fs->nactvar) { 27916a5fed65808adf648004b34f98718301d718fa2darylm fs->freereg--; 28016a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(reg == fs->freereg); 28116a5fed65808adf648004b34f98718301d718fa2darylm } 28216a5fed65808adf648004b34f98718301d718fa2darylm} 28316a5fed65808adf648004b34f98718301d718fa2darylm 28416a5fed65808adf648004b34f98718301d718fa2darylm 28516a5fed65808adf648004b34f98718301d718fa2darylmstatic void freeexp (FuncState *fs, expdesc *e) { 28616a5fed65808adf648004b34f98718301d718fa2darylm if (e->k == VNONRELOC) 28716a5fed65808adf648004b34f98718301d718fa2darylm freereg(fs, e->u.info); 28816a5fed65808adf648004b34f98718301d718fa2darylm} 28916a5fed65808adf648004b34f98718301d718fa2darylm 29016a5fed65808adf648004b34f98718301d718fa2darylm 29116a5fed65808adf648004b34f98718301d718fa2darylmstatic int addk (FuncState *fs, TValue *key, TValue *v) { 29216a5fed65808adf648004b34f98718301d718fa2darylm lua_State *L = fs->ls->L; 29316a5fed65808adf648004b34f98718301d718fa2darylm TValue *idx = luaH_set(L, fs->h, key); 29416a5fed65808adf648004b34f98718301d718fa2darylm Proto *f = fs->f; 29516a5fed65808adf648004b34f98718301d718fa2darylm int k, oldsize; 29616a5fed65808adf648004b34f98718301d718fa2darylm if (ttisnumber(idx)) { 29716a5fed65808adf648004b34f98718301d718fa2darylm lua_Number n = nvalue(idx); 29816a5fed65808adf648004b34f98718301d718fa2darylm lua_number2int(k, n); 29916a5fed65808adf648004b34f98718301d718fa2darylm if (luaV_rawequalobj(&f->k[k], v)) 30016a5fed65808adf648004b34f98718301d718fa2darylm return k; 30116a5fed65808adf648004b34f98718301d718fa2darylm /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); 30216a5fed65808adf648004b34f98718301d718fa2darylm go through and create a new entry for this value */ 30316a5fed65808adf648004b34f98718301d718fa2darylm } 30416a5fed65808adf648004b34f98718301d718fa2darylm /* constant not found; create a new entry */ 30516a5fed65808adf648004b34f98718301d718fa2darylm oldsize = f->sizek; 30616a5fed65808adf648004b34f98718301d718fa2darylm k = fs->nk; 30716a5fed65808adf648004b34f98718301d718fa2darylm /* numerical value does not need GC barrier; 30816a5fed65808adf648004b34f98718301d718fa2darylm table has no metatable, so it does not need to invalidate cache */ 30916a5fed65808adf648004b34f98718301d718fa2darylm setnvalue(idx, cast_num(k)); 31016a5fed65808adf648004b34f98718301d718fa2darylm luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); 31116a5fed65808adf648004b34f98718301d718fa2darylm while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); 31216a5fed65808adf648004b34f98718301d718fa2darylm setobj(L, &f->k[k], v); 31316a5fed65808adf648004b34f98718301d718fa2darylm fs->nk++; 31416a5fed65808adf648004b34f98718301d718fa2darylm luaC_barrier(L, f, v); 31516a5fed65808adf648004b34f98718301d718fa2darylm return k; 31616a5fed65808adf648004b34f98718301d718fa2darylm} 31716a5fed65808adf648004b34f98718301d718fa2darylm 31816a5fed65808adf648004b34f98718301d718fa2darylm 31916a5fed65808adf648004b34f98718301d718fa2darylmint luaK_stringK (FuncState *fs, TString *s) { 32016a5fed65808adf648004b34f98718301d718fa2darylm TValue o; 32116a5fed65808adf648004b34f98718301d718fa2darylm setsvalue(fs->ls->L, &o, s); 32216a5fed65808adf648004b34f98718301d718fa2darylm return addk(fs, &o, &o); 32316a5fed65808adf648004b34f98718301d718fa2darylm} 32416a5fed65808adf648004b34f98718301d718fa2darylm 32516a5fed65808adf648004b34f98718301d718fa2darylm 32616a5fed65808adf648004b34f98718301d718fa2darylmint luaK_numberK (FuncState *fs, lua_Number r) { 32716a5fed65808adf648004b34f98718301d718fa2darylm int n; 32816a5fed65808adf648004b34f98718301d718fa2darylm lua_State *L = fs->ls->L; 32916a5fed65808adf648004b34f98718301d718fa2darylm TValue o; 33016a5fed65808adf648004b34f98718301d718fa2darylm setnvalue(&o, r); 33116a5fed65808adf648004b34f98718301d718fa2darylm if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */ 33216a5fed65808adf648004b34f98718301d718fa2darylm /* use raw representation as key to avoid numeric problems */ 33316a5fed65808adf648004b34f98718301d718fa2darylm setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r))); 33416a5fed65808adf648004b34f98718301d718fa2darylm n = addk(fs, L->top - 1, &o); 33516a5fed65808adf648004b34f98718301d718fa2darylm L->top--; 33616a5fed65808adf648004b34f98718301d718fa2darylm } 33716a5fed65808adf648004b34f98718301d718fa2darylm else 33816a5fed65808adf648004b34f98718301d718fa2darylm n = addk(fs, &o, &o); /* regular case */ 33916a5fed65808adf648004b34f98718301d718fa2darylm return n; 34016a5fed65808adf648004b34f98718301d718fa2darylm} 34116a5fed65808adf648004b34f98718301d718fa2darylm 34216a5fed65808adf648004b34f98718301d718fa2darylm 34316a5fed65808adf648004b34f98718301d718fa2darylmstatic int boolK (FuncState *fs, int b) { 34416a5fed65808adf648004b34f98718301d718fa2darylm TValue o; 34516a5fed65808adf648004b34f98718301d718fa2darylm setbvalue(&o, b); 34616a5fed65808adf648004b34f98718301d718fa2darylm return addk(fs, &o, &o); 34716a5fed65808adf648004b34f98718301d718fa2darylm} 34816a5fed65808adf648004b34f98718301d718fa2darylm 34916a5fed65808adf648004b34f98718301d718fa2darylm 35016a5fed65808adf648004b34f98718301d718fa2darylmstatic int nilK (FuncState *fs) { 35116a5fed65808adf648004b34f98718301d718fa2darylm TValue k, v; 35216a5fed65808adf648004b34f98718301d718fa2darylm setnilvalue(&v); 35316a5fed65808adf648004b34f98718301d718fa2darylm /* cannot use nil as key; instead use table itself to represent nil */ 35416a5fed65808adf648004b34f98718301d718fa2darylm sethvalue(fs->ls->L, &k, fs->h); 35516a5fed65808adf648004b34f98718301d718fa2darylm return addk(fs, &k, &v); 35616a5fed65808adf648004b34f98718301d718fa2darylm} 35716a5fed65808adf648004b34f98718301d718fa2darylm 35816a5fed65808adf648004b34f98718301d718fa2darylm 35916a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { 36016a5fed65808adf648004b34f98718301d718fa2darylm if (e->k == VCALL) { /* expression is an open function call? */ 36116a5fed65808adf648004b34f98718301d718fa2darylm SETARG_C(getcode(fs, e), nresults+1); 36216a5fed65808adf648004b34f98718301d718fa2darylm } 36316a5fed65808adf648004b34f98718301d718fa2darylm else if (e->k == VVARARG) { 36416a5fed65808adf648004b34f98718301d718fa2darylm SETARG_B(getcode(fs, e), nresults+1); 36516a5fed65808adf648004b34f98718301d718fa2darylm SETARG_A(getcode(fs, e), fs->freereg); 36616a5fed65808adf648004b34f98718301d718fa2darylm luaK_reserveregs(fs, 1); 36716a5fed65808adf648004b34f98718301d718fa2darylm } 36816a5fed65808adf648004b34f98718301d718fa2darylm} 36916a5fed65808adf648004b34f98718301d718fa2darylm 37016a5fed65808adf648004b34f98718301d718fa2darylm 37116a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_setoneret (FuncState *fs, expdesc *e) { 37216a5fed65808adf648004b34f98718301d718fa2darylm if (e->k == VCALL) { /* expression is an open function call? */ 37316a5fed65808adf648004b34f98718301d718fa2darylm e->k = VNONRELOC; 37416a5fed65808adf648004b34f98718301d718fa2darylm e->u.info = GETARG_A(getcode(fs, e)); 37516a5fed65808adf648004b34f98718301d718fa2darylm } 37616a5fed65808adf648004b34f98718301d718fa2darylm else if (e->k == VVARARG) { 37716a5fed65808adf648004b34f98718301d718fa2darylm SETARG_B(getcode(fs, e), 2); 37816a5fed65808adf648004b34f98718301d718fa2darylm e->k = VRELOCABLE; /* can relocate its simple result */ 37916a5fed65808adf648004b34f98718301d718fa2darylm } 38016a5fed65808adf648004b34f98718301d718fa2darylm} 38116a5fed65808adf648004b34f98718301d718fa2darylm 38216a5fed65808adf648004b34f98718301d718fa2darylm 38316a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_dischargevars (FuncState *fs, expdesc *e) { 38416a5fed65808adf648004b34f98718301d718fa2darylm switch (e->k) { 38516a5fed65808adf648004b34f98718301d718fa2darylm case VLOCAL: { 38616a5fed65808adf648004b34f98718301d718fa2darylm e->k = VNONRELOC; 38716a5fed65808adf648004b34f98718301d718fa2darylm break; 38816a5fed65808adf648004b34f98718301d718fa2darylm } 38916a5fed65808adf648004b34f98718301d718fa2darylm case VUPVAL: { 39016a5fed65808adf648004b34f98718301d718fa2darylm e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); 39116a5fed65808adf648004b34f98718301d718fa2darylm e->k = VRELOCABLE; 39216a5fed65808adf648004b34f98718301d718fa2darylm break; 39316a5fed65808adf648004b34f98718301d718fa2darylm } 39416a5fed65808adf648004b34f98718301d718fa2darylm case VINDEXED: { 39516a5fed65808adf648004b34f98718301d718fa2darylm OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */ 39616a5fed65808adf648004b34f98718301d718fa2darylm freereg(fs, e->u.ind.idx); 39716a5fed65808adf648004b34f98718301d718fa2darylm if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */ 39816a5fed65808adf648004b34f98718301d718fa2darylm freereg(fs, e->u.ind.t); 39916a5fed65808adf648004b34f98718301d718fa2darylm op = OP_GETTABLE; 40016a5fed65808adf648004b34f98718301d718fa2darylm } 40116a5fed65808adf648004b34f98718301d718fa2darylm e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx); 40216a5fed65808adf648004b34f98718301d718fa2darylm e->k = VRELOCABLE; 40316a5fed65808adf648004b34f98718301d718fa2darylm break; 40416a5fed65808adf648004b34f98718301d718fa2darylm } 40516a5fed65808adf648004b34f98718301d718fa2darylm case VVARARG: 40616a5fed65808adf648004b34f98718301d718fa2darylm case VCALL: { 40716a5fed65808adf648004b34f98718301d718fa2darylm luaK_setoneret(fs, e); 40816a5fed65808adf648004b34f98718301d718fa2darylm break; 40916a5fed65808adf648004b34f98718301d718fa2darylm } 41016a5fed65808adf648004b34f98718301d718fa2darylm default: break; /* there is one value available (somewhere) */ 41116a5fed65808adf648004b34f98718301d718fa2darylm } 41216a5fed65808adf648004b34f98718301d718fa2darylm} 41316a5fed65808adf648004b34f98718301d718fa2darylm 41416a5fed65808adf648004b34f98718301d718fa2darylm 41516a5fed65808adf648004b34f98718301d718fa2darylmstatic int code_label (FuncState *fs, int A, int b, int jump) { 41616a5fed65808adf648004b34f98718301d718fa2darylm luaK_getlabel(fs); /* those instructions may be jump targets */ 41716a5fed65808adf648004b34f98718301d718fa2darylm return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); 41816a5fed65808adf648004b34f98718301d718fa2darylm} 41916a5fed65808adf648004b34f98718301d718fa2darylm 42016a5fed65808adf648004b34f98718301d718fa2darylm 42116a5fed65808adf648004b34f98718301d718fa2darylmstatic void discharge2reg (FuncState *fs, expdesc *e, int reg) { 42216a5fed65808adf648004b34f98718301d718fa2darylm luaK_dischargevars(fs, e); 42316a5fed65808adf648004b34f98718301d718fa2darylm switch (e->k) { 42416a5fed65808adf648004b34f98718301d718fa2darylm case VNIL: { 42516a5fed65808adf648004b34f98718301d718fa2darylm luaK_nil(fs, reg, 1); 42616a5fed65808adf648004b34f98718301d718fa2darylm break; 42716a5fed65808adf648004b34f98718301d718fa2darylm } 42816a5fed65808adf648004b34f98718301d718fa2darylm case VFALSE: case VTRUE: { 42916a5fed65808adf648004b34f98718301d718fa2darylm luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); 43016a5fed65808adf648004b34f98718301d718fa2darylm break; 43116a5fed65808adf648004b34f98718301d718fa2darylm } 43216a5fed65808adf648004b34f98718301d718fa2darylm case VK: { 43316a5fed65808adf648004b34f98718301d718fa2darylm luaK_codek(fs, reg, e->u.info); 43416a5fed65808adf648004b34f98718301d718fa2darylm break; 43516a5fed65808adf648004b34f98718301d718fa2darylm } 43616a5fed65808adf648004b34f98718301d718fa2darylm case VKNUM: { 43716a5fed65808adf648004b34f98718301d718fa2darylm luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval)); 43816a5fed65808adf648004b34f98718301d718fa2darylm break; 43916a5fed65808adf648004b34f98718301d718fa2darylm } 44016a5fed65808adf648004b34f98718301d718fa2darylm case VRELOCABLE: { 44116a5fed65808adf648004b34f98718301d718fa2darylm Instruction *pc = &getcode(fs, e); 44216a5fed65808adf648004b34f98718301d718fa2darylm SETARG_A(*pc, reg); 44316a5fed65808adf648004b34f98718301d718fa2darylm break; 44416a5fed65808adf648004b34f98718301d718fa2darylm } 44516a5fed65808adf648004b34f98718301d718fa2darylm case VNONRELOC: { 44616a5fed65808adf648004b34f98718301d718fa2darylm if (reg != e->u.info) 44716a5fed65808adf648004b34f98718301d718fa2darylm luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); 44816a5fed65808adf648004b34f98718301d718fa2darylm break; 44916a5fed65808adf648004b34f98718301d718fa2darylm } 45016a5fed65808adf648004b34f98718301d718fa2darylm default: { 45116a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(e->k == VVOID || e->k == VJMP); 45216a5fed65808adf648004b34f98718301d718fa2darylm return; /* nothing to do... */ 45316a5fed65808adf648004b34f98718301d718fa2darylm } 45416a5fed65808adf648004b34f98718301d718fa2darylm } 45516a5fed65808adf648004b34f98718301d718fa2darylm e->u.info = reg; 45616a5fed65808adf648004b34f98718301d718fa2darylm e->k = VNONRELOC; 45716a5fed65808adf648004b34f98718301d718fa2darylm} 45816a5fed65808adf648004b34f98718301d718fa2darylm 45916a5fed65808adf648004b34f98718301d718fa2darylm 46016a5fed65808adf648004b34f98718301d718fa2darylmstatic void discharge2anyreg (FuncState *fs, expdesc *e) { 46116a5fed65808adf648004b34f98718301d718fa2darylm if (e->k != VNONRELOC) { 46216a5fed65808adf648004b34f98718301d718fa2darylm luaK_reserveregs(fs, 1); 46316a5fed65808adf648004b34f98718301d718fa2darylm discharge2reg(fs, e, fs->freereg-1); 46416a5fed65808adf648004b34f98718301d718fa2darylm } 46516a5fed65808adf648004b34f98718301d718fa2darylm} 46616a5fed65808adf648004b34f98718301d718fa2darylm 46716a5fed65808adf648004b34f98718301d718fa2darylm 46816a5fed65808adf648004b34f98718301d718fa2darylmstatic void exp2reg (FuncState *fs, expdesc *e, int reg) { 46916a5fed65808adf648004b34f98718301d718fa2darylm discharge2reg(fs, e, reg); 47016a5fed65808adf648004b34f98718301d718fa2darylm if (e->k == VJMP) 47116a5fed65808adf648004b34f98718301d718fa2darylm luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */ 47216a5fed65808adf648004b34f98718301d718fa2darylm if (hasjumps(e)) { 47316a5fed65808adf648004b34f98718301d718fa2darylm int final; /* position after whole expression */ 47416a5fed65808adf648004b34f98718301d718fa2darylm int p_f = NO_JUMP; /* position of an eventual LOAD false */ 47516a5fed65808adf648004b34f98718301d718fa2darylm int p_t = NO_JUMP; /* position of an eventual LOAD true */ 47616a5fed65808adf648004b34f98718301d718fa2darylm if (need_value(fs, e->t) || need_value(fs, e->f)) { 47716a5fed65808adf648004b34f98718301d718fa2darylm int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); 47816a5fed65808adf648004b34f98718301d718fa2darylm p_f = code_label(fs, reg, 0, 1); 47916a5fed65808adf648004b34f98718301d718fa2darylm p_t = code_label(fs, reg, 1, 0); 48016a5fed65808adf648004b34f98718301d718fa2darylm luaK_patchtohere(fs, fj); 48116a5fed65808adf648004b34f98718301d718fa2darylm } 48216a5fed65808adf648004b34f98718301d718fa2darylm final = luaK_getlabel(fs); 48316a5fed65808adf648004b34f98718301d718fa2darylm patchlistaux(fs, e->f, final, reg, p_f); 48416a5fed65808adf648004b34f98718301d718fa2darylm patchlistaux(fs, e->t, final, reg, p_t); 48516a5fed65808adf648004b34f98718301d718fa2darylm } 48616a5fed65808adf648004b34f98718301d718fa2darylm e->f = e->t = NO_JUMP; 48716a5fed65808adf648004b34f98718301d718fa2darylm e->u.info = reg; 48816a5fed65808adf648004b34f98718301d718fa2darylm e->k = VNONRELOC; 48916a5fed65808adf648004b34f98718301d718fa2darylm} 49016a5fed65808adf648004b34f98718301d718fa2darylm 49116a5fed65808adf648004b34f98718301d718fa2darylm 49216a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_exp2nextreg (FuncState *fs, expdesc *e) { 49316a5fed65808adf648004b34f98718301d718fa2darylm luaK_dischargevars(fs, e); 49416a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, e); 49516a5fed65808adf648004b34f98718301d718fa2darylm luaK_reserveregs(fs, 1); 49616a5fed65808adf648004b34f98718301d718fa2darylm exp2reg(fs, e, fs->freereg - 1); 49716a5fed65808adf648004b34f98718301d718fa2darylm} 49816a5fed65808adf648004b34f98718301d718fa2darylm 49916a5fed65808adf648004b34f98718301d718fa2darylm 50016a5fed65808adf648004b34f98718301d718fa2darylmint luaK_exp2anyreg (FuncState *fs, expdesc *e) { 50116a5fed65808adf648004b34f98718301d718fa2darylm luaK_dischargevars(fs, e); 50216a5fed65808adf648004b34f98718301d718fa2darylm if (e->k == VNONRELOC) { 50316a5fed65808adf648004b34f98718301d718fa2darylm if (!hasjumps(e)) return e->u.info; /* exp is already in a register */ 50416a5fed65808adf648004b34f98718301d718fa2darylm if (e->u.info >= fs->nactvar) { /* reg. is not a local? */ 50516a5fed65808adf648004b34f98718301d718fa2darylm exp2reg(fs, e, e->u.info); /* put value on it */ 50616a5fed65808adf648004b34f98718301d718fa2darylm return e->u.info; 50716a5fed65808adf648004b34f98718301d718fa2darylm } 50816a5fed65808adf648004b34f98718301d718fa2darylm } 50916a5fed65808adf648004b34f98718301d718fa2darylm luaK_exp2nextreg(fs, e); /* default */ 51016a5fed65808adf648004b34f98718301d718fa2darylm return e->u.info; 51116a5fed65808adf648004b34f98718301d718fa2darylm} 51216a5fed65808adf648004b34f98718301d718fa2darylm 51316a5fed65808adf648004b34f98718301d718fa2darylm 51416a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_exp2anyregup (FuncState *fs, expdesc *e) { 51516a5fed65808adf648004b34f98718301d718fa2darylm if (e->k != VUPVAL || hasjumps(e)) 51616a5fed65808adf648004b34f98718301d718fa2darylm luaK_exp2anyreg(fs, e); 51716a5fed65808adf648004b34f98718301d718fa2darylm} 51816a5fed65808adf648004b34f98718301d718fa2darylm 51916a5fed65808adf648004b34f98718301d718fa2darylm 52016a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_exp2val (FuncState *fs, expdesc *e) { 52116a5fed65808adf648004b34f98718301d718fa2darylm if (hasjumps(e)) 52216a5fed65808adf648004b34f98718301d718fa2darylm luaK_exp2anyreg(fs, e); 52316a5fed65808adf648004b34f98718301d718fa2darylm else 52416a5fed65808adf648004b34f98718301d718fa2darylm luaK_dischargevars(fs, e); 52516a5fed65808adf648004b34f98718301d718fa2darylm} 52616a5fed65808adf648004b34f98718301d718fa2darylm 52716a5fed65808adf648004b34f98718301d718fa2darylm 52816a5fed65808adf648004b34f98718301d718fa2darylmint luaK_exp2RK (FuncState *fs, expdesc *e) { 52916a5fed65808adf648004b34f98718301d718fa2darylm luaK_exp2val(fs, e); 53016a5fed65808adf648004b34f98718301d718fa2darylm switch (e->k) { 53116a5fed65808adf648004b34f98718301d718fa2darylm case VTRUE: 53216a5fed65808adf648004b34f98718301d718fa2darylm case VFALSE: 53316a5fed65808adf648004b34f98718301d718fa2darylm case VNIL: { 53416a5fed65808adf648004b34f98718301d718fa2darylm if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */ 53516a5fed65808adf648004b34f98718301d718fa2darylm e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE)); 53616a5fed65808adf648004b34f98718301d718fa2darylm e->k = VK; 53716a5fed65808adf648004b34f98718301d718fa2darylm return RKASK(e->u.info); 53816a5fed65808adf648004b34f98718301d718fa2darylm } 53916a5fed65808adf648004b34f98718301d718fa2darylm else break; 54016a5fed65808adf648004b34f98718301d718fa2darylm } 54116a5fed65808adf648004b34f98718301d718fa2darylm case VKNUM: { 54216a5fed65808adf648004b34f98718301d718fa2darylm e->u.info = luaK_numberK(fs, e->u.nval); 54316a5fed65808adf648004b34f98718301d718fa2darylm e->k = VK; 54416a5fed65808adf648004b34f98718301d718fa2darylm /* go through */ 54516a5fed65808adf648004b34f98718301d718fa2darylm } 54616a5fed65808adf648004b34f98718301d718fa2darylm case VK: { 54716a5fed65808adf648004b34f98718301d718fa2darylm if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */ 54816a5fed65808adf648004b34f98718301d718fa2darylm return RKASK(e->u.info); 54916a5fed65808adf648004b34f98718301d718fa2darylm else break; 55016a5fed65808adf648004b34f98718301d718fa2darylm } 55116a5fed65808adf648004b34f98718301d718fa2darylm default: break; 55216a5fed65808adf648004b34f98718301d718fa2darylm } 55316a5fed65808adf648004b34f98718301d718fa2darylm /* not a constant in the right range: put it in a register */ 55416a5fed65808adf648004b34f98718301d718fa2darylm return luaK_exp2anyreg(fs, e); 55516a5fed65808adf648004b34f98718301d718fa2darylm} 55616a5fed65808adf648004b34f98718301d718fa2darylm 55716a5fed65808adf648004b34f98718301d718fa2darylm 55816a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { 55916a5fed65808adf648004b34f98718301d718fa2darylm switch (var->k) { 56016a5fed65808adf648004b34f98718301d718fa2darylm case VLOCAL: { 56116a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, ex); 56216a5fed65808adf648004b34f98718301d718fa2darylm exp2reg(fs, ex, var->u.info); 56316a5fed65808adf648004b34f98718301d718fa2darylm return; 56416a5fed65808adf648004b34f98718301d718fa2darylm } 56516a5fed65808adf648004b34f98718301d718fa2darylm case VUPVAL: { 56616a5fed65808adf648004b34f98718301d718fa2darylm int e = luaK_exp2anyreg(fs, ex); 56716a5fed65808adf648004b34f98718301d718fa2darylm luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); 56816a5fed65808adf648004b34f98718301d718fa2darylm break; 56916a5fed65808adf648004b34f98718301d718fa2darylm } 57016a5fed65808adf648004b34f98718301d718fa2darylm case VINDEXED: { 57116a5fed65808adf648004b34f98718301d718fa2darylm OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP; 57216a5fed65808adf648004b34f98718301d718fa2darylm int e = luaK_exp2RK(fs, ex); 57316a5fed65808adf648004b34f98718301d718fa2darylm luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e); 57416a5fed65808adf648004b34f98718301d718fa2darylm break; 57516a5fed65808adf648004b34f98718301d718fa2darylm } 57616a5fed65808adf648004b34f98718301d718fa2darylm default: { 57716a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(0); /* invalid var kind to store */ 57816a5fed65808adf648004b34f98718301d718fa2darylm break; 57916a5fed65808adf648004b34f98718301d718fa2darylm } 58016a5fed65808adf648004b34f98718301d718fa2darylm } 58116a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, ex); 58216a5fed65808adf648004b34f98718301d718fa2darylm} 58316a5fed65808adf648004b34f98718301d718fa2darylm 58416a5fed65808adf648004b34f98718301d718fa2darylm 58516a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_self (FuncState *fs, expdesc *e, expdesc *key) { 58616a5fed65808adf648004b34f98718301d718fa2darylm int ereg; 58716a5fed65808adf648004b34f98718301d718fa2darylm luaK_exp2anyreg(fs, e); 58816a5fed65808adf648004b34f98718301d718fa2darylm ereg = e->u.info; /* register where 'e' was placed */ 58916a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, e); 59016a5fed65808adf648004b34f98718301d718fa2darylm e->u.info = fs->freereg; /* base register for op_self */ 59116a5fed65808adf648004b34f98718301d718fa2darylm e->k = VNONRELOC; 59216a5fed65808adf648004b34f98718301d718fa2darylm luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ 59316a5fed65808adf648004b34f98718301d718fa2darylm luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); 59416a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, key); 59516a5fed65808adf648004b34f98718301d718fa2darylm} 59616a5fed65808adf648004b34f98718301d718fa2darylm 59716a5fed65808adf648004b34f98718301d718fa2darylm 59816a5fed65808adf648004b34f98718301d718fa2darylmstatic void invertjump (FuncState *fs, expdesc *e) { 59916a5fed65808adf648004b34f98718301d718fa2darylm Instruction *pc = getjumpcontrol(fs, e->u.info); 60016a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && 60116a5fed65808adf648004b34f98718301d718fa2darylm GET_OPCODE(*pc) != OP_TEST); 60216a5fed65808adf648004b34f98718301d718fa2darylm SETARG_A(*pc, !(GETARG_A(*pc))); 60316a5fed65808adf648004b34f98718301d718fa2darylm} 60416a5fed65808adf648004b34f98718301d718fa2darylm 60516a5fed65808adf648004b34f98718301d718fa2darylm 60616a5fed65808adf648004b34f98718301d718fa2darylmstatic int jumponcond (FuncState *fs, expdesc *e, int cond) { 60716a5fed65808adf648004b34f98718301d718fa2darylm if (e->k == VRELOCABLE) { 60816a5fed65808adf648004b34f98718301d718fa2darylm Instruction ie = getcode(fs, e); 60916a5fed65808adf648004b34f98718301d718fa2darylm if (GET_OPCODE(ie) == OP_NOT) { 61016a5fed65808adf648004b34f98718301d718fa2darylm fs->pc--; /* remove previous OP_NOT */ 61116a5fed65808adf648004b34f98718301d718fa2darylm return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); 61216a5fed65808adf648004b34f98718301d718fa2darylm } 61316a5fed65808adf648004b34f98718301d718fa2darylm /* else go through */ 61416a5fed65808adf648004b34f98718301d718fa2darylm } 61516a5fed65808adf648004b34f98718301d718fa2darylm discharge2anyreg(fs, e); 61616a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, e); 61716a5fed65808adf648004b34f98718301d718fa2darylm return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); 61816a5fed65808adf648004b34f98718301d718fa2darylm} 61916a5fed65808adf648004b34f98718301d718fa2darylm 62016a5fed65808adf648004b34f98718301d718fa2darylm 62116a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_goiftrue (FuncState *fs, expdesc *e) { 62216a5fed65808adf648004b34f98718301d718fa2darylm int pc; /* pc of last jump */ 62316a5fed65808adf648004b34f98718301d718fa2darylm luaK_dischargevars(fs, e); 62416a5fed65808adf648004b34f98718301d718fa2darylm switch (e->k) { 62516a5fed65808adf648004b34f98718301d718fa2darylm case VJMP: { 62616a5fed65808adf648004b34f98718301d718fa2darylm invertjump(fs, e); 62716a5fed65808adf648004b34f98718301d718fa2darylm pc = e->u.info; 62816a5fed65808adf648004b34f98718301d718fa2darylm break; 62916a5fed65808adf648004b34f98718301d718fa2darylm } 63016a5fed65808adf648004b34f98718301d718fa2darylm case VK: case VKNUM: case VTRUE: { 63116a5fed65808adf648004b34f98718301d718fa2darylm pc = NO_JUMP; /* always true; do nothing */ 63216a5fed65808adf648004b34f98718301d718fa2darylm break; 63316a5fed65808adf648004b34f98718301d718fa2darylm } 63416a5fed65808adf648004b34f98718301d718fa2darylm default: { 63516a5fed65808adf648004b34f98718301d718fa2darylm pc = jumponcond(fs, e, 0); 63616a5fed65808adf648004b34f98718301d718fa2darylm break; 63716a5fed65808adf648004b34f98718301d718fa2darylm } 63816a5fed65808adf648004b34f98718301d718fa2darylm } 63916a5fed65808adf648004b34f98718301d718fa2darylm luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ 64016a5fed65808adf648004b34f98718301d718fa2darylm luaK_patchtohere(fs, e->t); 64116a5fed65808adf648004b34f98718301d718fa2darylm e->t = NO_JUMP; 64216a5fed65808adf648004b34f98718301d718fa2darylm} 64316a5fed65808adf648004b34f98718301d718fa2darylm 64416a5fed65808adf648004b34f98718301d718fa2darylm 64516a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_goiffalse (FuncState *fs, expdesc *e) { 64616a5fed65808adf648004b34f98718301d718fa2darylm int pc; /* pc of last jump */ 64716a5fed65808adf648004b34f98718301d718fa2darylm luaK_dischargevars(fs, e); 64816a5fed65808adf648004b34f98718301d718fa2darylm switch (e->k) { 64916a5fed65808adf648004b34f98718301d718fa2darylm case VJMP: { 65016a5fed65808adf648004b34f98718301d718fa2darylm pc = e->u.info; 65116a5fed65808adf648004b34f98718301d718fa2darylm break; 65216a5fed65808adf648004b34f98718301d718fa2darylm } 65316a5fed65808adf648004b34f98718301d718fa2darylm case VNIL: case VFALSE: { 65416a5fed65808adf648004b34f98718301d718fa2darylm pc = NO_JUMP; /* always false; do nothing */ 65516a5fed65808adf648004b34f98718301d718fa2darylm break; 65616a5fed65808adf648004b34f98718301d718fa2darylm } 65716a5fed65808adf648004b34f98718301d718fa2darylm default: { 65816a5fed65808adf648004b34f98718301d718fa2darylm pc = jumponcond(fs, e, 1); 65916a5fed65808adf648004b34f98718301d718fa2darylm break; 66016a5fed65808adf648004b34f98718301d718fa2darylm } 66116a5fed65808adf648004b34f98718301d718fa2darylm } 66216a5fed65808adf648004b34f98718301d718fa2darylm luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ 66316a5fed65808adf648004b34f98718301d718fa2darylm luaK_patchtohere(fs, e->f); 66416a5fed65808adf648004b34f98718301d718fa2darylm e->f = NO_JUMP; 66516a5fed65808adf648004b34f98718301d718fa2darylm} 66616a5fed65808adf648004b34f98718301d718fa2darylm 66716a5fed65808adf648004b34f98718301d718fa2darylm 66816a5fed65808adf648004b34f98718301d718fa2darylmstatic void codenot (FuncState *fs, expdesc *e) { 66916a5fed65808adf648004b34f98718301d718fa2darylm luaK_dischargevars(fs, e); 67016a5fed65808adf648004b34f98718301d718fa2darylm switch (e->k) { 67116a5fed65808adf648004b34f98718301d718fa2darylm case VNIL: case VFALSE: { 67216a5fed65808adf648004b34f98718301d718fa2darylm e->k = VTRUE; 67316a5fed65808adf648004b34f98718301d718fa2darylm break; 67416a5fed65808adf648004b34f98718301d718fa2darylm } 67516a5fed65808adf648004b34f98718301d718fa2darylm case VK: case VKNUM: case VTRUE: { 67616a5fed65808adf648004b34f98718301d718fa2darylm e->k = VFALSE; 67716a5fed65808adf648004b34f98718301d718fa2darylm break; 67816a5fed65808adf648004b34f98718301d718fa2darylm } 67916a5fed65808adf648004b34f98718301d718fa2darylm case VJMP: { 68016a5fed65808adf648004b34f98718301d718fa2darylm invertjump(fs, e); 68116a5fed65808adf648004b34f98718301d718fa2darylm break; 68216a5fed65808adf648004b34f98718301d718fa2darylm } 68316a5fed65808adf648004b34f98718301d718fa2darylm case VRELOCABLE: 68416a5fed65808adf648004b34f98718301d718fa2darylm case VNONRELOC: { 68516a5fed65808adf648004b34f98718301d718fa2darylm discharge2anyreg(fs, e); 68616a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, e); 68716a5fed65808adf648004b34f98718301d718fa2darylm e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); 68816a5fed65808adf648004b34f98718301d718fa2darylm e->k = VRELOCABLE; 68916a5fed65808adf648004b34f98718301d718fa2darylm break; 69016a5fed65808adf648004b34f98718301d718fa2darylm } 69116a5fed65808adf648004b34f98718301d718fa2darylm default: { 69216a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(0); /* cannot happen */ 69316a5fed65808adf648004b34f98718301d718fa2darylm break; 69416a5fed65808adf648004b34f98718301d718fa2darylm } 69516a5fed65808adf648004b34f98718301d718fa2darylm } 69616a5fed65808adf648004b34f98718301d718fa2darylm /* interchange true and false lists */ 69716a5fed65808adf648004b34f98718301d718fa2darylm { int temp = e->f; e->f = e->t; e->t = temp; } 69816a5fed65808adf648004b34f98718301d718fa2darylm removevalues(fs, e->f); 69916a5fed65808adf648004b34f98718301d718fa2darylm removevalues(fs, e->t); 70016a5fed65808adf648004b34f98718301d718fa2darylm} 70116a5fed65808adf648004b34f98718301d718fa2darylm 70216a5fed65808adf648004b34f98718301d718fa2darylm 70316a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { 70416a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(!hasjumps(t)); 70516a5fed65808adf648004b34f98718301d718fa2darylm t->u.ind.t = (lu_byte)t->u.info; 70616a5fed65808adf648004b34f98718301d718fa2darylm t->u.ind.idx = (short)luaK_exp2RK(fs, k); 70716a5fed65808adf648004b34f98718301d718fa2darylm t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL 70816a5fed65808adf648004b34f98718301d718fa2darylm : check_exp(vkisinreg(t->k), VLOCAL); 70916a5fed65808adf648004b34f98718301d718fa2darylm t->k = VINDEXED; 71016a5fed65808adf648004b34f98718301d718fa2darylm} 71116a5fed65808adf648004b34f98718301d718fa2darylm 71216a5fed65808adf648004b34f98718301d718fa2darylm 71316a5fed65808adf648004b34f98718301d718fa2darylmstatic int constfolding (OpCode op, expdesc *e1, expdesc *e2) { 71416a5fed65808adf648004b34f98718301d718fa2darylm lua_Number r; 71516a5fed65808adf648004b34f98718301d718fa2darylm if (!isnumeral(e1) || !isnumeral(e2)) return 0; 71616a5fed65808adf648004b34f98718301d718fa2darylm if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0) 71716a5fed65808adf648004b34f98718301d718fa2darylm return 0; /* do not attempt to divide by 0 */ 71816a5fed65808adf648004b34f98718301d718fa2darylm r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval); 71916a5fed65808adf648004b34f98718301d718fa2darylm e1->u.nval = r; 72016a5fed65808adf648004b34f98718301d718fa2darylm return 1; 72116a5fed65808adf648004b34f98718301d718fa2darylm} 72216a5fed65808adf648004b34f98718301d718fa2darylm 72316a5fed65808adf648004b34f98718301d718fa2darylm 72416a5fed65808adf648004b34f98718301d718fa2darylmstatic void codearith (FuncState *fs, OpCode op, 72516a5fed65808adf648004b34f98718301d718fa2darylm expdesc *e1, expdesc *e2, int line) { 72616a5fed65808adf648004b34f98718301d718fa2darylm if (constfolding(op, e1, e2)) 72716a5fed65808adf648004b34f98718301d718fa2darylm return; 72816a5fed65808adf648004b34f98718301d718fa2darylm else { 72916a5fed65808adf648004b34f98718301d718fa2darylm int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; 73016a5fed65808adf648004b34f98718301d718fa2darylm int o1 = luaK_exp2RK(fs, e1); 73116a5fed65808adf648004b34f98718301d718fa2darylm if (o1 > o2) { 73216a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, e1); 73316a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, e2); 73416a5fed65808adf648004b34f98718301d718fa2darylm } 73516a5fed65808adf648004b34f98718301d718fa2darylm else { 73616a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, e2); 73716a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, e1); 73816a5fed65808adf648004b34f98718301d718fa2darylm } 73916a5fed65808adf648004b34f98718301d718fa2darylm e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); 74016a5fed65808adf648004b34f98718301d718fa2darylm e1->k = VRELOCABLE; 74116a5fed65808adf648004b34f98718301d718fa2darylm luaK_fixline(fs, line); 74216a5fed65808adf648004b34f98718301d718fa2darylm } 74316a5fed65808adf648004b34f98718301d718fa2darylm} 74416a5fed65808adf648004b34f98718301d718fa2darylm 74516a5fed65808adf648004b34f98718301d718fa2darylm 74616a5fed65808adf648004b34f98718301d718fa2darylmstatic void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, 74716a5fed65808adf648004b34f98718301d718fa2darylm expdesc *e2) { 74816a5fed65808adf648004b34f98718301d718fa2darylm int o1 = luaK_exp2RK(fs, e1); 74916a5fed65808adf648004b34f98718301d718fa2darylm int o2 = luaK_exp2RK(fs, e2); 75016a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, e2); 75116a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, e1); 75216a5fed65808adf648004b34f98718301d718fa2darylm if (cond == 0 && op != OP_EQ) { 75316a5fed65808adf648004b34f98718301d718fa2darylm int temp; /* exchange args to replace by `<' or `<=' */ 75416a5fed65808adf648004b34f98718301d718fa2darylm temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ 75516a5fed65808adf648004b34f98718301d718fa2darylm cond = 1; 75616a5fed65808adf648004b34f98718301d718fa2darylm } 75716a5fed65808adf648004b34f98718301d718fa2darylm e1->u.info = condjump(fs, op, cond, o1, o2); 75816a5fed65808adf648004b34f98718301d718fa2darylm e1->k = VJMP; 75916a5fed65808adf648004b34f98718301d718fa2darylm} 76016a5fed65808adf648004b34f98718301d718fa2darylm 76116a5fed65808adf648004b34f98718301d718fa2darylm 76216a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { 76316a5fed65808adf648004b34f98718301d718fa2darylm expdesc e2; 76416a5fed65808adf648004b34f98718301d718fa2darylm e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; 76516a5fed65808adf648004b34f98718301d718fa2darylm switch (op) { 76616a5fed65808adf648004b34f98718301d718fa2darylm case OPR_MINUS: { 76716a5fed65808adf648004b34f98718301d718fa2darylm if (isnumeral(e)) /* minus constant? */ 76816a5fed65808adf648004b34f98718301d718fa2darylm e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */ 76916a5fed65808adf648004b34f98718301d718fa2darylm else { 77016a5fed65808adf648004b34f98718301d718fa2darylm luaK_exp2anyreg(fs, e); 77116a5fed65808adf648004b34f98718301d718fa2darylm codearith(fs, OP_UNM, e, &e2, line); 77216a5fed65808adf648004b34f98718301d718fa2darylm } 77316a5fed65808adf648004b34f98718301d718fa2darylm break; 77416a5fed65808adf648004b34f98718301d718fa2darylm } 77516a5fed65808adf648004b34f98718301d718fa2darylm case OPR_NOT: codenot(fs, e); break; 77616a5fed65808adf648004b34f98718301d718fa2darylm case OPR_LEN: { 77716a5fed65808adf648004b34f98718301d718fa2darylm luaK_exp2anyreg(fs, e); /* cannot operate on constants */ 77816a5fed65808adf648004b34f98718301d718fa2darylm codearith(fs, OP_LEN, e, &e2, line); 77916a5fed65808adf648004b34f98718301d718fa2darylm break; 78016a5fed65808adf648004b34f98718301d718fa2darylm } 78116a5fed65808adf648004b34f98718301d718fa2darylm default: lua_assert(0); 78216a5fed65808adf648004b34f98718301d718fa2darylm } 78316a5fed65808adf648004b34f98718301d718fa2darylm} 78416a5fed65808adf648004b34f98718301d718fa2darylm 78516a5fed65808adf648004b34f98718301d718fa2darylm 78616a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { 78716a5fed65808adf648004b34f98718301d718fa2darylm switch (op) { 78816a5fed65808adf648004b34f98718301d718fa2darylm case OPR_AND: { 78916a5fed65808adf648004b34f98718301d718fa2darylm luaK_goiftrue(fs, v); 79016a5fed65808adf648004b34f98718301d718fa2darylm break; 79116a5fed65808adf648004b34f98718301d718fa2darylm } 79216a5fed65808adf648004b34f98718301d718fa2darylm case OPR_OR: { 79316a5fed65808adf648004b34f98718301d718fa2darylm luaK_goiffalse(fs, v); 79416a5fed65808adf648004b34f98718301d718fa2darylm break; 79516a5fed65808adf648004b34f98718301d718fa2darylm } 79616a5fed65808adf648004b34f98718301d718fa2darylm case OPR_CONCAT: { 79716a5fed65808adf648004b34f98718301d718fa2darylm luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ 79816a5fed65808adf648004b34f98718301d718fa2darylm break; 79916a5fed65808adf648004b34f98718301d718fa2darylm } 80016a5fed65808adf648004b34f98718301d718fa2darylm case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: 80116a5fed65808adf648004b34f98718301d718fa2darylm case OPR_MOD: case OPR_POW: { 80216a5fed65808adf648004b34f98718301d718fa2darylm if (!isnumeral(v)) luaK_exp2RK(fs, v); 80316a5fed65808adf648004b34f98718301d718fa2darylm break; 80416a5fed65808adf648004b34f98718301d718fa2darylm } 80516a5fed65808adf648004b34f98718301d718fa2darylm default: { 80616a5fed65808adf648004b34f98718301d718fa2darylm luaK_exp2RK(fs, v); 80716a5fed65808adf648004b34f98718301d718fa2darylm break; 80816a5fed65808adf648004b34f98718301d718fa2darylm } 80916a5fed65808adf648004b34f98718301d718fa2darylm } 81016a5fed65808adf648004b34f98718301d718fa2darylm} 81116a5fed65808adf648004b34f98718301d718fa2darylm 81216a5fed65808adf648004b34f98718301d718fa2darylm 81316a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_posfix (FuncState *fs, BinOpr op, 81416a5fed65808adf648004b34f98718301d718fa2darylm expdesc *e1, expdesc *e2, int line) { 81516a5fed65808adf648004b34f98718301d718fa2darylm switch (op) { 81616a5fed65808adf648004b34f98718301d718fa2darylm case OPR_AND: { 81716a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(e1->t == NO_JUMP); /* list must be closed */ 81816a5fed65808adf648004b34f98718301d718fa2darylm luaK_dischargevars(fs, e2); 81916a5fed65808adf648004b34f98718301d718fa2darylm luaK_concat(fs, &e2->f, e1->f); 82016a5fed65808adf648004b34f98718301d718fa2darylm *e1 = *e2; 82116a5fed65808adf648004b34f98718301d718fa2darylm break; 82216a5fed65808adf648004b34f98718301d718fa2darylm } 82316a5fed65808adf648004b34f98718301d718fa2darylm case OPR_OR: { 82416a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(e1->f == NO_JUMP); /* list must be closed */ 82516a5fed65808adf648004b34f98718301d718fa2darylm luaK_dischargevars(fs, e2); 82616a5fed65808adf648004b34f98718301d718fa2darylm luaK_concat(fs, &e2->t, e1->t); 82716a5fed65808adf648004b34f98718301d718fa2darylm *e1 = *e2; 82816a5fed65808adf648004b34f98718301d718fa2darylm break; 82916a5fed65808adf648004b34f98718301d718fa2darylm } 83016a5fed65808adf648004b34f98718301d718fa2darylm case OPR_CONCAT: { 83116a5fed65808adf648004b34f98718301d718fa2darylm luaK_exp2val(fs, e2); 83216a5fed65808adf648004b34f98718301d718fa2darylm if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { 83316a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1); 83416a5fed65808adf648004b34f98718301d718fa2darylm freeexp(fs, e1); 83516a5fed65808adf648004b34f98718301d718fa2darylm SETARG_B(getcode(fs, e2), e1->u.info); 83616a5fed65808adf648004b34f98718301d718fa2darylm e1->k = VRELOCABLE; e1->u.info = e2->u.info; 83716a5fed65808adf648004b34f98718301d718fa2darylm } 83816a5fed65808adf648004b34f98718301d718fa2darylm else { 83916a5fed65808adf648004b34f98718301d718fa2darylm luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ 84016a5fed65808adf648004b34f98718301d718fa2darylm codearith(fs, OP_CONCAT, e1, e2, line); 84116a5fed65808adf648004b34f98718301d718fa2darylm } 84216a5fed65808adf648004b34f98718301d718fa2darylm break; 84316a5fed65808adf648004b34f98718301d718fa2darylm } 84416a5fed65808adf648004b34f98718301d718fa2darylm case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: 84516a5fed65808adf648004b34f98718301d718fa2darylm case OPR_MOD: case OPR_POW: { 84616a5fed65808adf648004b34f98718301d718fa2darylm codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); 84716a5fed65808adf648004b34f98718301d718fa2darylm break; 84816a5fed65808adf648004b34f98718301d718fa2darylm } 84916a5fed65808adf648004b34f98718301d718fa2darylm case OPR_EQ: case OPR_LT: case OPR_LE: { 85016a5fed65808adf648004b34f98718301d718fa2darylm codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2); 85116a5fed65808adf648004b34f98718301d718fa2darylm break; 85216a5fed65808adf648004b34f98718301d718fa2darylm } 85316a5fed65808adf648004b34f98718301d718fa2darylm case OPR_NE: case OPR_GT: case OPR_GE: { 85416a5fed65808adf648004b34f98718301d718fa2darylm codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2); 85516a5fed65808adf648004b34f98718301d718fa2darylm break; 85616a5fed65808adf648004b34f98718301d718fa2darylm } 85716a5fed65808adf648004b34f98718301d718fa2darylm default: lua_assert(0); 85816a5fed65808adf648004b34f98718301d718fa2darylm } 85916a5fed65808adf648004b34f98718301d718fa2darylm} 86016a5fed65808adf648004b34f98718301d718fa2darylm 86116a5fed65808adf648004b34f98718301d718fa2darylm 86216a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_fixline (FuncState *fs, int line) { 86316a5fed65808adf648004b34f98718301d718fa2darylm fs->f->lineinfo[fs->pc - 1] = line; 86416a5fed65808adf648004b34f98718301d718fa2darylm} 86516a5fed65808adf648004b34f98718301d718fa2darylm 86616a5fed65808adf648004b34f98718301d718fa2darylm 86716a5fed65808adf648004b34f98718301d718fa2darylmvoid luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { 86816a5fed65808adf648004b34f98718301d718fa2darylm int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; 86916a5fed65808adf648004b34f98718301d718fa2darylm int b = (tostore == LUA_MULTRET) ? 0 : tostore; 87016a5fed65808adf648004b34f98718301d718fa2darylm lua_assert(tostore != 0); 87116a5fed65808adf648004b34f98718301d718fa2darylm if (c <= MAXARG_C) 87216a5fed65808adf648004b34f98718301d718fa2darylm luaK_codeABC(fs, OP_SETLIST, base, b, c); 87316a5fed65808adf648004b34f98718301d718fa2darylm else if (c <= MAXARG_Ax) { 87416a5fed65808adf648004b34f98718301d718fa2darylm luaK_codeABC(fs, OP_SETLIST, base, b, 0); 87516a5fed65808adf648004b34f98718301d718fa2darylm codeextraarg(fs, c); 87616a5fed65808adf648004b34f98718301d718fa2darylm } 87716a5fed65808adf648004b34f98718301d718fa2darylm else 87816a5fed65808adf648004b34f98718301d718fa2darylm luaX_syntaxerror(fs->ls, "constructor too long"); 87916a5fed65808adf648004b34f98718301d718fa2darylm fs->freereg = (lu_byte)base + 1; /* free registers with list values */ 88016a5fed65808adf648004b34f98718301d718fa2darylm} 88116a5fed65808adf648004b34f98718301d718fa2darylm 882