From 9621add2918cc4943e6693b74ae85d51dd264fcf Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Mon, 21 Apr 2014 20:59:39 +1000 Subject: We don't need the testlua directory any more. --- LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua | 902 ---------------------- 1 file changed, 902 deletions(-) delete mode 100644 LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua (limited to 'LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua') diff --git a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua b/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua deleted file mode 100644 index c18dc08..0000000 --- a/LuaSL/testLua/yueliang-0.4.1/orig-5.0.3/lcode.lua +++ /dev/null @@ -1,902 +0,0 @@ ---[[-------------------------------------------------------------------- - - lcode.lua - Lua 5 code generator in Lua - This file is part of Yueliang. - - Copyright (c) 2005-2006 Kein-Hong Man - The COPYRIGHT file describes the conditions - under which this software may be distributed. - - See the ChangeLog for more information. - -----------------------------------------------------------------------]] - ---[[-------------------------------------------------------------------- --- Notes: --- * one function manipulate a pointer argument with a simple data type --- (can't be emulated by a table, ambiguous), now returns that value: --- luaK:concat(fs, l1, l2) --- * some function parameters changed to boolean, additional code --- translates boolean back to 1/0 for instruction fields --- * Added: --- luaK:ttisnumber(o) (from lobject.h) --- luaK:nvalue(o) (from lobject.h) --- luaK:setnilvalue(o) (from lobject.h) --- luaK:setsvalue(o, x) (from lobject.h) --- luaK:setnvalue(o, x) (from lobject.h) --- luaK:sethvalue(o, x) (from lobject.h) -----------------------------------------------------------------------]] - --- requires luaP, luaX, luaY -luaK = {} - ------------------------------------------------------------------------- --- Marks the end of a patch list. It is an invalid value both as an absolute --- address, and as a list link (would link an element to itself). ------------------------------------------------------------------------- -luaK.NO_JUMP = -1 - ------------------------------------------------------------------------- --- grep "ORDER OPR" if you change these enums ------------------------------------------------------------------------- -luaK.BinOpr = { - OPR_ADD = 0, OPR_SUB = 1, OPR_MULT = 2, OPR_DIV = 3, OPR_POW = 4, - OPR_CONCAT = 5, - OPR_NE = 6, OPR_EQ = 7, - OPR_LT = 8, OPR_LE = 9, OPR_GT = 10, OPR_GE = 11, - OPR_AND = 12, OPR_OR = 13, - OPR_NOBINOPR = 14, -} - ------------------------------------------------------------------------- --- emulation of TObject macros (these are from lobject.h) --- * TObject is a table since lcode passes references around --- * tt member field removed, using Lua's type() instead ------------------------------------------------------------------------- -function luaK:ttisnumber(o) - if o then return type(o.value) == "number" else return false end -end -function luaK:nvalue(o) return o.value end -function luaK:setnilvalue(o) o.value = nil end -function luaK:setsvalue(o, x) o.value = x end -luaK.setnvalue = luaK.setsvalue -luaK.sethvalue = luaK.setsvalue - ------------------------------------------------------------------------- --- * binopistest appears to be unused --- * UnOpr is used by luaK:prefix's op argument ------------------------------------------------------------------------- -function luaK:binopistest(op) - return self.BinOpr[op] >= self.BinOpr["OPR_NE"] -end - -luaK.UnOpr = { - OPR_MINUS = 0, OPR_NOT = 1, OPR_NOUNOPR = 2 -} - ------------------------------------------------------------------------- --- returns the instruction object for given e (expdesc) ------------------------------------------------------------------------- -function luaK:getcode(fs, e) - return fs.f.code[e.info] -end - ------------------------------------------------------------------------- --- codes an instruction with a signed Bx (sBx) field ------------------------------------------------------------------------- -function luaK:codeAsBx(fs, o, A, sBx) - return self:codeABx(fs, o, A, sBx + luaP.MAXARG_sBx) -end - ------------------------------------------------------------------------- --- there is a jump if patch lists are not identical --- * used in luaK:exp2reg(), luaK:exp2anyreg(), luaK:exp2val() ------------------------------------------------------------------------- -function luaK:hasjumps(e) - return e.t ~= e.f -end - ------------------------------------------------------------------------- --- codes loading of nil, optimization done if consecutive locations --- * used only in discharge2reg() ------------------------------------------------------------------------- -function luaK:_nil(fs, from, n) - if fs.pc > fs.lasttarget then -- no jumps to current position? - local previous = fs.f.code[fs.pc - 1] - if luaP:GET_OPCODE(previous) == "OP_LOADNIL" then - local pfrom = luaP:GETARG_A(previous) - local pto = luaP:GETARG_B(previous) - if pfrom <= from and from <= pto + 1 then -- can connect both? - if from + n - 1 > pto then - luaP:SETARG_B(previous, from + n - 1) - end - return - end - end - end - self:codeABC(fs, "OP_LOADNIL", from, from + n - 1, 0) -- else no optimization -end - ------------------------------------------------------------------------- --- --- * used in multiple locations ------------------------------------------------------------------------- -function luaK:jump(fs) - local jpc = fs.jpc -- save list of jumps to here - fs.jpc = self.NO_JUMP - local j = self:codeAsBx(fs, "OP_JMP", 0, self.NO_JUMP) - return self:concat(fs, j, jpc) -- keep them on hold -end - ------------------------------------------------------------------------- --- --- * used in luaK:jumponcond(), luaK:codebinop() ------------------------------------------------------------------------- -function luaK:condjump(fs, op, A, B, C) - self:codeABC(fs, op, A, B, C) - return self:jump(fs) -end - ------------------------------------------------------------------------- --- --- * used in luaK:patchlistaux(), luaK:concat() ------------------------------------------------------------------------- -function luaK:fixjump(fs, pc, dest) - local jmp = fs.f.code[pc] - local offset = dest - (pc + 1) - lua_assert(dest ~= self.NO_JUMP) - if math.abs(offset) > luaP.MAXARG_sBx then - luaX:syntaxerror(fs.ls, "control structure too long") - end - luaP:SETARG_sBx(jmp, offset) -end - ------------------------------------------------------------------------- --- returns current 'pc' and marks it as a jump target (to avoid wrong --- optimizations with consecutive instructions not in the same basic block). --- * used in multiple locations --- * fs.lasttarget tested only by luaK:_nil() when optimizing OP_LOADNIL ------------------------------------------------------------------------- -function luaK:getlabel(fs) - fs.lasttarget = fs.pc - return fs.pc -end - ------------------------------------------------------------------------- --- --- * used in luaK:need_value(), luaK:patchlistaux(), luaK:concat() ------------------------------------------------------------------------- -function luaK:getjump(fs, pc) - local offset = luaP:GETARG_sBx(fs.f.code[pc]) - if offset == self.NO_JUMP then -- point to itself represents end of list - return self.NO_JUMP -- end of list - else - return (pc + 1) + offset -- turn offset into absolute position - end -end - ------------------------------------------------------------------------- --- --- * used in luaK:need_value(), luaK:patchlistaux(), luaK:invertjump() ------------------------------------------------------------------------- -function luaK:getjumpcontrol(fs, pc) - local pi = fs.f.code[pc] - local ppi = fs.f.code[pc - 1] - if pc >= 1 and luaP:testOpMode(luaP:GET_OPCODE(ppi), "OpModeT") then - return ppi - else - return pi - end -end - ------------------------------------------------------------------------- --- check whether list has any jump that do not produce a value --- (or produce an inverted value) --- * used only in luaK:exp2reg() ------------------------------------------------------------------------- -function luaK:need_value(fs, list, cond) - while list ~= self.NO_JUMP do - local i = self:getjumpcontrol(fs, list) - if luaP:GET_OPCODE(i) ~= "OP_TEST" or - luaP:GETARG_A(i) ~= luaP.NO_REG or - luaP:GETARG_C(i) ~= cond then - return true - end - list = self:getjump(fs, list) - end - return false -- not found -end - ------------------------------------------------------------------------- --- --- * used only in luaK:patchlistaux() ------------------------------------------------------------------------- -function luaK:patchtestreg(i, reg) - if reg == luaP.NO_REG then reg = luaP:GETARG_B(i) end - luaP:SETARG_A(i, reg) -end - ------------------------------------------------------------------------- --- --- * used only in luaK:codenot() ------------------------------------------------------------------------- - -function luaK:removevalues(fs, list) - while list ~= self.NO_JUMP do - local i = self:getjumpcontrol(fs, list) - if luaP:GET_OPCODE(i) == "OP_TEST" then - self:patchtestreg(i, luaP.NO_REG) - end - list = self:getjump(fs, list) - end -end - ------------------------------------------------------------------------- --- --- * used in luaK:dischargejpc(), luaK:patchlist(), luaK:exp2reg() ------------------------------------------------------------------------- -function luaK:patchlistaux(fs, list, vtarget, reg, dtarget) - while list ~= self.NO_JUMP do - local _next = self:getjump(fs, list) - local i = self:getjumpcontrol(fs, list) - if luaP:GET_OPCODE(i) == "OP_TEST" and luaP:GETARG_A(i) == luaP.NO_REG then - self:patchtestreg(i, reg) - self:fixjump(fs, list, vtarget) - else - self:fixjump(fs, list, dtarget) -- jump to default target - end - list = _next - end -end - ------------------------------------------------------------------------- --- --- * used only in luaK:code() ------------------------------------------------------------------------- -function luaK:dischargejpc(fs) - self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc) - fs.jpc = self.NO_JUMP -end - ------------------------------------------------------------------------- --- --- * used in (lparser) luaY:whilestat(), luaY:repeatstat(), luaY:forbody() ------------------------------------------------------------------------- -function luaK:patchlist(fs, list, target) - if target == fs.pc then - self:patchtohere(fs, list) - else - lua_assert(target < fs.pc) - self:patchlistaux(fs, list, target, luaP.NO_REG, target) - end -end - ------------------------------------------------------------------------- --- --- * used in multiple locations ------------------------------------------------------------------------- -function luaK:patchtohere(fs, list) - self:getlabel(fs) - fs.jpc = self:concat(fs, fs.jpc, list) -end - ------------------------------------------------------------------------- --- * l1 was a pointer, now l1 is returned and callee assigns the value --- * used in multiple locations ------------------------------------------------------------------------- -function luaK:concat(fs, l1, l2) - if l2 == self.NO_JUMP then return l1 -- unchanged - elseif l1 == self.NO_JUMP then - return l2 -- changed - else - local list = l1 - local _next = self:getjump(fs, list) - while _next ~= self.NO_JUMP do -- find last element - list = _next - _next = self:getjump(fs, list) - end - self:fixjump(fs, list, l2) - end - return l1 -- unchanged -end - ------------------------------------------------------------------------- --- --- * used in luaK:reserveregs(), (lparser) luaY:forlist() ------------------------------------------------------------------------- -function luaK:checkstack(fs, n) - local newstack = fs.freereg + n - if newstack > fs.f.maxstacksize then - if newstack >= luaY.MAXSTACK then - luaX:syntaxerror(fs.ls, "function or expression too complex") - end - fs.f.maxstacksize = newstack - end -end - ------------------------------------------------------------------------- --- --- * used in multiple locations ------------------------------------------------------------------------- -function luaK:reserveregs(fs, n) - self:checkstack(fs, n) - fs.freereg = fs.freereg + n -end - ------------------------------------------------------------------------- --- --- * used in luaK:freeexp(), luaK:dischargevars() ------------------------------------------------------------------------- -function luaK:freereg(fs, reg) - if reg >= fs.nactvar and reg < luaY.MAXSTACK then - fs.freereg = fs.freereg - 1 - lua_assert(reg == fs.freereg) - end -end - ------------------------------------------------------------------------- --- --- * used in multiple locations ------------------------------------------------------------------------- -function luaK:freeexp(fs, e) - if e.k == "VNONRELOC" then - self:freereg(fs, e.info) - end -end - ------------------------------------------------------------------------- --- * luaH_get, luaH_set deleted; direct table access used instead --- * luaO_rawequalObj deleted in first assert --- * setobj2n deleted in assignment of v to f.k table --- * used in luaK:stringK(), luaK:numberK(), luaK:nil_constant() ------------------------------------------------------------------------- -function luaK:addk(fs, k, v) - local idx = fs.h[k.value] - if self:ttisnumber(idx) then - --TODO this assert currently FAILS, probably something wrong... - --lua_assert(fs.f.k[self:nvalue(idx)] == v) - return self:nvalue(idx) - else -- constant not found; create a new entry - local f = fs.f - luaY:growvector(fs.L, f.k, fs.nk, f.sizek, nil, - luaP.MAXARG_Bx, "constant table overflow") - f.k[fs.nk] = v -- setobj2n deleted - fs.h[k.value] = {} - self:setnvalue(fs.h[k.value], fs.nk) - local nk = fs.nk - fs.nk = fs.nk + 1 - return nk - end -end - ------------------------------------------------------------------------- --- creates and sets a string object --- * used in (lparser) luaY:codestring(), luaY:singlevaraux() ------------------------------------------------------------------------- -function luaK:stringK(fs, s) - local o = {} -- TObject - self:setsvalue(o, s) - return self:addk(fs, o, o) -end - ------------------------------------------------------------------------- --- creates and sets a number object --- * used in luaK:prefix() for negative (or negation of) numbers --- * used in (lparser) luaY:simpleexp(), luaY:fornum() ------------------------------------------------------------------------- -function luaK:numberK(fs, r) - local o = {} -- TObject - self:setnvalue(o, r) - return self:addk(fs, o, o) -end - ------------------------------------------------------------------------- --- --- * used only in luaK:exp2RK() ------------------------------------------------------------------------- -function luaK:nil_constant(fs) - local k, v = {}, {} -- TObject - self:setnilvalue(v) - self:sethvalue(k, fs.h) -- cannot use nil as key; instead use table itself - return self:addk(fs, k, v) -end - ------------------------------------------------------------------------- --- --- * used in luaK:dischargevars() --- * used in (lparser) luaY:adjust_assign(), luaY:lastlistfield(), --- luaY:funcargs(), luaY:assignment(), luaY:exprstat(), luaY:retstat() ------------------------------------------------------------------------- -function luaK:setcallreturns(fs, e, nresults) - if e.k == "VCALL" then -- expression is an open function call? - luaP:SETARG_C(self:getcode(fs, e), nresults + 1) - if nresults == 1 then -- 'regular' expression? - e.k = "VNONRELOC" - e.info = luaP:GETARG_A(self:getcode(fs, e)) - end - end -end - ------------------------------------------------------------------------- --- --- * used in multiple locations ------------------------------------------------------------------------- -function luaK:dischargevars(fs, e) - local k = e.k - if k == "VLOCAL" then - e.k = "VNONRELOC" - elseif k == "VUPVAL" then - e.info = self:codeABC(fs, "OP_GETUPVAL", 0, e.info, 0) - e.k = "VRELOCABLE" - elseif k == "VGLOBAL" then - e.info = self:codeABx(fs, "OP_GETGLOBAL", 0, e.info) - e.k = "VRELOCABLE" - elseif k == "VINDEXED" then - self:freereg(fs, e.aux) - self:freereg(fs, e.info) - e.info = self:codeABC(fs, "OP_GETTABLE", 0, e.info, e.aux) - e.k = "VRELOCABLE" - elseif k == "VCALL" then - self:setcallreturns(fs, e, 1) - else - -- there is one value available (somewhere) - end -end - ------------------------------------------------------------------------- --- --- * used only in luaK:exp2reg() ------------------------------------------------------------------------- -function luaK:code_label(fs, A, b, jump) - self:getlabel(fs) -- those instructions may be jump targets - return self:codeABC(fs, "OP_LOADBOOL", A, b, jump) -end - ------------------------------------------------------------------------- --- --- * used in luaK:discharge2anyreg(), luaK:exp2reg() ------------------------------------------------------------------------- -function luaK:discharge2reg(fs, e, reg) - self:dischargevars(fs, e) - local k = e.k - if k == "VNIL" then - self:_nil(fs, reg, 1) - elseif k == "VFALSE" or k == "VTRUE" then - self:codeABC(fs, "OP_LOADBOOL", reg, (e.k == "VTRUE") and 1 or 0, 0) - elseif k == "VK" then - self:codeABx(fs, "OP_LOADK", reg, e.info) - elseif k == "VRELOCABLE" then - local pc = self:getcode(fs, e) - luaP:SETARG_A(pc, reg) - elseif k == "VNONRELOC" then - if reg ~= e.info then - self:codeABC(fs, "OP_MOVE", reg, e.info, 0) - end - else - lua_assert(e.k == "VVOID" or e.k == "VJMP") - return -- nothing to do... - end - e.info = reg - e.k = "VNONRELOC" -end - ------------------------------------------------------------------------- --- --- * used in luaK:jumponcond(), luaK:codenot() ------------------------------------------------------------------------- -function luaK:discharge2anyreg(fs, e) - if e.k ~= "VNONRELOC" then - self:reserveregs(fs, 1) - self:discharge2reg(fs, e, fs.freereg - 1) - end -end - ------------------------------------------------------------------------- --- --- * used in luaK:exp2nextreg(), luaK:exp2anyreg(), luaK:storevar() ------------------------------------------------------------------------- -function luaK:exp2reg(fs, e, reg) - self:discharge2reg(fs, e, reg) - if e.k == "VJMP" then - e.t = self:concat(fs, e.t, e.info) -- put this jump in 't' list - end - if self:hasjumps(e) then - local final -- position after whole expression - local p_f = self.NO_JUMP -- position of an eventual LOAD false - local p_t = self.NO_JUMP -- position of an eventual LOAD true - if self:need_value(fs, e.t, 1) or self:need_value(fs, e.f, 0) then - local fj = self.NO_JUMP -- first jump (over LOAD ops.) - if e.k ~= "VJMP" then - fj = self:jump(fs) - end - p_f = self:code_label(fs, reg, 0, 1) - p_t = self:code_label(fs, reg, 1, 0) - self:patchtohere(fs, fj) - end - final = self:getlabel(fs) - self:patchlistaux(fs, e.f, final, reg, p_f) - self:patchlistaux(fs, e.t, final, reg, p_t) - end - e.f, e.t = self.NO_JUMP, self.NO_JUMP - e.info = reg - e.k = "VNONRELOC" -end - ------------------------------------------------------------------------- --- --- * used in multiple locations ------------------------------------------------------------------------- -function luaK:exp2nextreg(fs, e) - self:dischargevars(fs, e) - self:freeexp(fs, e) - self:reserveregs(fs, 1) - self:exp2reg(fs, e, fs.freereg - 1) -end - ------------------------------------------------------------------------- --- --- * used in multiple locations ------------------------------------------------------------------------- -function luaK:exp2anyreg(fs, e) - self:dischargevars(fs, e) - if e.k == "VNONRELOC" then - if not self:hasjumps(e) then -- exp is already in a register - return e.info - end - if e.info >= fs.nactvar then -- reg. is not a local? - self:exp2reg(fs, e, e.info) -- put value on it - return e.info - end - end - self:exp2nextreg(fs, e) -- default - return e.info -end - ------------------------------------------------------------------------- --- --- * used in luaK:exp2RK(), luaK:prefix(), luaK:posfix() --- * used in (lparser) luaY:index() ------------------------------------------------------------------------- -function luaK:exp2val(fs, e) - if self:hasjumps(e) then - self:exp2anyreg(fs, e) - else - self:dischargevars(fs, e) - end -end - ------------------------------------------------------------------------- --- --- * used in multiple locations ------------------------------------------------------------------------- -function luaK:exp2RK(fs, e) - self:exp2val(fs, e) - local k = e.k - if k == "VNIL" then - if fs.nk + luaY.MAXSTACK <= luaP.MAXARG_C then -- constant fit in argC? - e.info = self:nil_constant(fs) - e.k = "VK" - return e.info + luaY.MAXSTACK - end - elseif k == "VK" then - if e.info + luaY.MAXSTACK <= luaP.MAXARG_C then -- constant fit in argC? - return e.info + luaY.MAXSTACK - end - end - -- not a constant in the right range: put it in a register - return self:exp2anyreg(fs, e) -end - ------------------------------------------------------------------------- --- --- * used in (lparser) luaY:assignment(), luaY:localfunc(), luaY:funcstat() ------------------------------------------------------------------------- -function luaK:storevar(fs, var, exp) - local k = var.k - if k == "VLOCAL" then - self:freeexp(fs, exp) - self:exp2reg(fs, exp, var.info) - return - elseif k == "VUPVAL" then - local e = self:exp2anyreg(fs, exp) - self:codeABC(fs, "OP_SETUPVAL", e, var.info, 0) - elseif k == "VGLOBAL" then - local e = self:exp2anyreg(fs, exp) - self:codeABx(fs, "OP_SETGLOBAL", e, var.info) - elseif k == "VINDEXED" then - local e = self:exp2RK(fs, exp) - self:codeABC(fs, "OP_SETTABLE", var.info, var.aux, e) - else - lua_assert(0) -- invalid var kind to store - end - self:freeexp(fs, exp) -end - ------------------------------------------------------------------------- --- --- * used only in (lparser) luaY:primaryexp() ------------------------------------------------------------------------- -function luaK:_self(fs, e, key) - self:exp2anyreg(fs, e) - self:freeexp(fs, e) - local func = fs.freereg - self:reserveregs(fs, 2) - self:codeABC(fs, "OP_SELF", func, e.info, self:exp2RK(fs, key)) - self:freeexp(fs, key) - e.info = func - e.k = "VNONRELOC" -end - ------------------------------------------------------------------------- --- --- * used in luaK:goiftrue(), luaK:codenot() ------------------------------------------------------------------------- -function luaK:invertjump(fs, e) - local pc = self:getjumpcontrol(fs, e.info) - lua_assert(luaP:testOpMode(luaP:GET_OPCODE(pc), "OpModeT") and - luaP:GET_OPCODE(pc) ~= "OP_TEST") - luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0) -end - ------------------------------------------------------------------------- --- --- * used in luaK:goiftrue(), luaK:goiffalse() ------------------------------------------------------------------------- -function luaK:jumponcond(fs, e, cond) - if e.k == "VRELOCABLE" then - local ie = self:getcode(fs, e) - if luaP:GET_OPCODE(ie) == "OP_NOT" then - fs.pc = fs.pc - 1 -- remove previous OP_NOT - return self:condjump(fs, "OP_TEST", luaP:GETARG_B(ie), luaP:GETARG_B(ie), - cond and 0 or 1) - end - -- else go through - end - self:discharge2anyreg(fs, e) - self:freeexp(fs, e) - return self:condjump(fs, "OP_TEST", luaP.NO_REG, e.info, cond and 1 or 0) -end - ------------------------------------------------------------------------- --- --- * used in luaK:infix(), (lparser) luaY:cond() ------------------------------------------------------------------------- -function luaK:goiftrue(fs, e) - local pc -- pc of last jump - self:dischargevars(fs, e) - local k = e.k - if k == "VK" or k == "VTRUE" then - pc = self.NO_JUMP -- always true; do nothing - elseif k == "VFALSE" then - pc = self:jump(fs) -- always jump - elseif k == "VJMP" then - self:invertjump(fs, e) - pc = e.info - else - pc = self:jumponcond(fs, e, false) - end - e.f = self:concat(fs, e.f, pc) -- insert last jump in 'f' list -end - ------------------------------------------------------------------------- --- --- * used in luaK:infix(), (lparser) luaY:whilestat() ------------------------------------------------------------------------- -function luaK:goiffalse(fs, e) - local pc -- pc of last jump - self:dischargevars(fs, e) - local k = e.k - if k == "VNIL" or k == "VFALSE"then - pc = self.NO_JUMP -- always false; do nothing - elseif k == "VTRUE" then - pc = self:jump(fs) -- always jump - elseif k == "VJMP" then - pc = e.info - else - pc = self:jumponcond(fs, e, true) - end - e.t = self:concat(fs, e.t, pc) -- insert last jump in 't' list -end - ------------------------------------------------------------------------- --- --- * used only in luaK:prefix() ------------------------------------------------------------------------- -function luaK:codenot(fs, e) - self:dischargevars(fs, e) - local k = e.k - if k == "VNIL" or k == "VFALSE" then - e.k = "VTRUE" - elseif k == "VK" or k == "VTRUE" then - e.k = "VFALSE" - elseif k == "VJMP" then - self:invertjump(fs, e) - elseif k == "VRELOCABLE" or k == "VNONRELOC" then - self:discharge2anyreg(fs, e) - self:freeexp(fs, e) - e.info = self:codeABC(fs, "OP_NOT", 0, e.info, 0) - e.k = "VRELOCABLE" - else - lua_assert(0) -- cannot happen - end - -- interchange true and false lists - e.f, e.t = e.t, e.f - self:removevalues(fs, e.f) - self:removevalues(fs, e.t) -end - ------------------------------------------------------------------------- --- --- * used in (lparser) luaY:field(), luaY:primaryexp() ------------------------------------------------------------------------- -function luaK:indexed(fs, t, k) - t.aux = self:exp2RK(fs, k) - t.k = "VINDEXED" -end - ------------------------------------------------------------------------- --- --- * used only in (lparser) luaY:subexpr() ------------------------------------------------------------------------- -function luaK:prefix(fs, op, e) - if op == "OPR_MINUS" then - self:exp2val(fs, e) - if e.k == "VK" and self:ttisnumber(fs.f.k[e.info]) then - e.info = self:numberK(fs, -self:nvalue(fs.f.k[e.info])) - else - self:exp2anyreg(fs, e) - self:freeexp(fs, e) - e.info = self:codeABC(fs, "OP_UNM", 0, e.info, 0) - e.k = "VRELOCABLE" - end - else -- op == NOT - self:codenot(fs, e) - end -end - ------------------------------------------------------------------------- --- --- * used only in (lparser) luaY:subexpr() ------------------------------------------------------------------------- -function luaK:infix(fs, op, v) - if op == "OPR_AND" then - self:goiftrue(fs, v) - self:patchtohere(fs, v.t) - v.t = self.NO_JUMP - elseif op == "OPR_OR" then - self:goiffalse(fs, v) - self:patchtohere(fs, v.f) - v.f = self.NO_JUMP - elseif op == "OPR_CONCAT" then - self:exp2nextreg(fs, v) -- operand must be on the 'stack' - else - self:exp2RK(fs, v) - end -end - ------------------------------------------------------------------------- --- --- grep "ORDER OPR" if you change these enums --- * used only in luaK:posfix() ------------------------------------------------------------------------- -luaK.arith_opc = { -- done as a table lookup instead of a calc - OPR_ADD = "OP_ADD", - OPR_SUB = "OP_SUB", - OPR_MULT = "OP_MUL", - OPR_DIV = "OP_DIV", - OPR_POW = "OP_POW", -} -luaK.test_opc = { -- was ops[] in the codebinop function - OPR_NE = "OP_EQ", - OPR_EQ = "OP_EQ", - OPR_LT = "OP_LT", - OPR_LE = "OP_LE", - OPR_GT = "OP_LT", - OPR_GE = "OP_LE", -} -function luaK:codebinop(fs, res, op, o1, o2) - if self.BinOpr[op] <= self.BinOpr["OPR_POW"] then -- arithmetic operator? - local opc = self.arith_opc[op] -- ORDER OP - res.info = self:codeABC(fs, opc, 0, o1, o2) - res.k = "VRELOCABLE" - else -- test operator - local cond = true - if self.BinOpr[op] >= self.BinOpr["OPR_GT"] then -- '>' or '>='? - -- exchange args and replace by '<' or '<=' - o1, o2 = o2, o1 -- o1 <==> o2 - elseif op == "OPR_NE" then - cond = false - end - res.info = self:condjump(fs, self.test_opc[op], cond and 1 or 0, o1, o2) - res.k = "VJMP" - end -end - ------------------------------------------------------------------------- --- --- * used only in (lparser) luaY:subexpr() ------------------------------------------------------------------------- -function luaK:posfix(fs, op, e1, e2) - if op == "OPR_AND" then - lua_assert(e1.t == self.NO_JUMP) -- list must be closed - self:dischargevars(fs, e2) - e1.f = self:concat(fs, e1.f, e2.f) - e1.k = e2.k; e1.info = e2.info; e1.aux = e2.aux; e1.t = e2.t - elseif op == "OPR_OR" then - lua_assert(e1.f == self.NO_JUMP) -- list must be closed - self:dischargevars(fs, e2) - e1.t = self:concat(fs, e1.t, e2.t) - e1.k = e2.k; e1.info = e2.info; e1.aux = e2.aux; e1.f = e2.f - elseif op == "OPR_CONCAT" then - self:exp2val(fs, e2) - if e2.k == "VRELOCABLE" - and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then - lua_assert(e1.info == luaP:GETARG_B(self:getcode(fs, e2)) - 1) - self:freeexp(fs, e1) - luaP:SETARG_B(self:getcode(fs, e2), e1.info) - e1.k = e2.k; e1.info = e2.info - else - self:exp2nextreg(fs, e2) - self:freeexp(fs, e2) - self:freeexp(fs, e1) - e1.info = self:codeABC(fs, "OP_CONCAT", 0, e1.info, e2.info) - e1.k = "VRELOCABLE" - end - else - local o1 = self:exp2RK(fs, e1) - local o2 = self:exp2RK(fs, e2) - self:freeexp(fs, e2) - self:freeexp(fs, e1) - self:codebinop(fs, e1, op, o1, o2) - end -end - ------------------------------------------------------------------------- --- adjusts debug information for last instruction written, in order to --- change the line where item comes into existence --- * used in (lparser) luaY:funcargs(), luaY:forbody(), luaY:funcstat() ------------------------------------------------------------------------- -function luaK:fixline(fs, line) - fs.f.lineinfo[fs.pc - 1] = line -end - ------------------------------------------------------------------------- --- general function to write an instruction into the instruction buffer, --- sets debug information too --- * used in luaK:codeABC(), luaK:codeABx() --- * called directly by (lparser) luaY:whilestat() ------------------------------------------------------------------------- -function luaK:code(fs, i, line) - local f = fs.f - self:dischargejpc(fs) -- 'pc' will change - -- put new instruction in code array - luaY:growvector(fs.L, f.code, fs.pc, f.sizecode, nil, - luaY.MAX_INT, "code size overflow") - f.code[fs.pc] = i - -- save corresponding line information - luaY:growvector(fs.L, f.lineinfo, fs.pc, f.sizelineinfo, nil, - luaY.MAX_INT, "code size overflow") - f.lineinfo[fs.pc] = line - local pc = fs.pc - fs.pc = fs.pc + 1 - return pc -end - ------------------------------------------------------------------------- --- writes an instruction of type ABC --- * calls luaK:code() ------------------------------------------------------------------------- -function luaK:codeABC(fs, o, a, b, c) - lua_assert(luaP:getOpMode(o) == "iABC") - return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline) -end - ------------------------------------------------------------------------- --- writes an instruction of type ABx --- * calls luaK:code(), called by luaK:codeAsBx() ------------------------------------------------------------------------- -function luaK:codeABx(fs, o, a, bc) - lua_assert(luaP:getOpMode(o) == "iABx" or luaP:getOpMode(o) == "iAsBx") - return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline) -end -- cgit v1.1