diff --git a/build.xml b/build.xml index 4ee9fccd..29caece5 100644 --- a/build.xml +++ b/build.xml @@ -105,7 +105,9 @@ - + + + diff --git a/src/core/org/luaj/compiler/DumpState.java b/src/core/org/luaj/compiler/DumpState.java deleted file mode 100644 index a9ddd59e..00000000 --- a/src/core/org/luaj/compiler/DumpState.java +++ /dev/null @@ -1,269 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.compiler; - -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.luaj.vm.LNumber; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LString; -import org.luaj.vm.LValue; -import org.luaj.vm.LocVars; -import org.luaj.vm.Lua; - - -public class DumpState { - - /** mark for precompiled code (`Lua') */ - public static final String LUA_SIGNATURE = "\033Lua"; - - /** for header of binary files -- this is Lua 5.1 */ - public static final int LUAC_VERSION = 0x51; - - /** for header of binary files -- this is the official format */ - public static final int LUAC_FORMAT = 0; - - /** size of header of binary files */ - public static final int LUAC_HEADERSIZE = 12; - - /** expected lua header bytes */ - private static final byte[] LUAC_HEADER_SIGNATURE = { '\033', 'L', 'u', 'a' }; - - /** set true to allow integer compilation */ - public static boolean ALLOW_INTEGER_CASTING = false; - - /** format corresponding to non-number-patched lua, all numbers are floats or doubles */ - public static final int NUMBER_FORMAT_FLOATS_OR_DOUBLES = 0; - - /** format corresponding to non-number-patched lua, all numbers are ints */ - public static final int NUMBER_FORMAT_INTS_ONLY = 1; - - /** format corresponding to number-patched lua, all numbers are 32-bit (4 byte) ints */ - public static final int NUMBER_FORMAT_NUM_PATCH_INT32 = 4; - - /** default number format */ - public static final int NUMBER_FORMAT_DEFAULT = NUMBER_FORMAT_FLOATS_OR_DOUBLES; - - // header fields - private boolean IS_LITTLE_ENDIAN = false; - private int NUMBER_FORMAT = NUMBER_FORMAT_DEFAULT; - private int SIZEOF_LUA_NUMBER = 8; - private static final int SIZEOF_INT = 4; - private static final int SIZEOF_SIZET = 4; - private static final int SIZEOF_INSTRUCTION = 4; - - DataOutputStream writer; - boolean strip; - int status; - - public DumpState(OutputStream w, boolean strip) { - this.writer = new DataOutputStream( w ); - this.strip = strip; - this.status = 0; - } - - void dumpBlock(final byte[] b, int size) throws IOException { - writer.write(b, 0, size); - } - - void dumpChar(int b) throws IOException { - writer.write( b ); - } - - void dumpInt(int x) throws IOException { - if ( IS_LITTLE_ENDIAN ) { - writer.writeByte(x&0xff); - writer.writeByte((x>>8)&0xff); - writer.writeByte((x>>16)&0xff); - writer.writeByte((x>>24)&0xff); - } else { - writer.writeInt(x); - } - } - - void dumpString(LString s) throws IOException { - final int len = s.length(); - dumpInt( len+1 ); - s.write( writer, 0, len ); - writer.write( 0 ); - } - - void dumpDouble(double d) throws IOException { - long l = Double.doubleToLongBits(d); - if ( IS_LITTLE_ENDIAN ) { - dumpInt( (int) l ); - dumpInt( (int) (l>>32) ); - } else { - writer.writeLong(l); - } - } - - void dumpCode( final LPrototype f ) throws IOException { - final int[] code = f.code; - int n = code.length; - dumpInt( n ); - for ( int i=0; i l ) - errorlimit( l, msg ); - } - - void errorlimit (int limit, String what) { - String msg = (f.linedefined == 0) ? - L.pushfstring("main function has more than "+limit+" "+what) : - L.pushfstring("function at line "+f.linedefined+" has more than "+limit+" "+what); - ls.lexerror(msg, 0); - } - - - int indexupvalue(LString name, expdesc v) { - int i; - for (i = 0; i < f.nups; i++) { - if (upvalues[i].k == v.k && upvalues[i].info == v.u.s.info) { - _assert(f.upvalues[i] == name); - return i; - } - } - /* new one */ - checklimit(f.nups + 1, LUAI_MAXUPVALUES, "upvalues"); - if ( f.upvalues == null || f.nups + 1 > f.upvalues.length) - f.upvalues = realloc( f.upvalues, f.nups*2+1 ); - f.upvalues[f.nups] = name; - _assert (v.k == LexState.VLOCAL || v.k == LexState.VUPVAL); - upvalues[f.nups] = new upvaldesc(); - upvalues[f.nups].k = (byte) (v.k); - upvalues[f.nups].info = (byte) (v.u.s.info); - return f.nups++; - } - - int searchvar(LString n) { - int i; - for (i = nactvar - 1; i >= 0; i--) { - if (n == getlocvar(i).varname) - return i; - } - return -1; /* not found */ - } - - void markupval(int level) { - BlockCnt bl = this.bl; - while (bl != null && bl.nactvar > level) - bl = bl.previous; - if (bl != null) - bl.upval = true; - } - - int singlevaraux(LString n, expdesc var, int base) { - int v = searchvar(n); /* look up at current level */ - if (v >= 0) { - var.init(LexState.VLOCAL, v); - if (base == 0) - markupval(v); /* local will be used as an upval */ - return LexState.VLOCAL; - } else { /* not found at current level; try upper one */ - if (prev == null) { /* no more levels? */ - /* default is global variable */ - var.init(LexState.VGLOBAL, NO_REG); - return LexState.VGLOBAL; - } - if (prev.singlevaraux(n, var, 0) == LexState.VGLOBAL) - return LexState.VGLOBAL; - var.u.s.info = indexupvalue(n, var); /* else was LOCAL or UPVAL */ - var.k = LexState.VUPVAL; /* upvalue in this level */ - return LexState.VUPVAL; - } - } - - void enterblock (BlockCnt bl, boolean isbreakable) { - bl.breaklist.i = LexState.NO_JUMP; - bl.isbreakable = isbreakable; - bl.nactvar = this.nactvar; - bl.upval = false; - bl.previous = this.bl; - this.bl = bl; - _assert(this.freereg == this.nactvar); - } - - // -// void leaveblock (FuncState *fs) { -// BlockCnt *bl = this.bl; -// this.bl = bl.previous; -// removevars(this.ls, bl.nactvar); -// if (bl.upval) -// this.codeABC(OP_CLOSE, bl.nactvar, 0, 0); -// /* a block either controls scope or breaks (never both) */ -// assert(!bl.isbreakable || !bl.upval); -// assert(bl.nactvar == this.nactvar); -// this.freereg = this.nactvar; /* free registers */ -// this.patchtohere(bl.breaklist); -// } - - void leaveblock() { - BlockCnt bl = this.bl; - this.bl = bl.previous; - ls.removevars(bl.nactvar); - if (bl.upval) - this.codeABC(OP_CLOSE, bl.nactvar, 0, 0); - /* a block either controls scope or breaks (never both) */ - _assert (!bl.isbreakable || !bl.upval); - _assert (bl.nactvar == this.nactvar); - this.freereg = this.nactvar; /* free registers */ - this.patchtohere(bl.breaklist.i); - } - - void closelistfield(ConsControl cc) { - if (cc.v.k == LexState.VVOID) - return; /* there is no list item */ - this.exp2nextreg(cc.v); - cc.v.k = LexState.VVOID; - if (cc.tostore == LFIELDS_PER_FLUSH) { - this.setlist(cc.t.u.s.info, cc.na, cc.tostore); /* flush */ - cc.tostore = 0; /* no more items pending */ - } - } - - boolean hasmultret(int k) { - return ((k) == LexState.VCALL || (k) == LexState.VVARARG); - } - - void lastlistfield (ConsControl cc) { - if (cc.tostore == 0) return; - if (hasmultret(cc.v.k)) { - this.setmultret(cc.v); - this.setlist(cc.t.u.s.info, cc.na, LUA_MULTRET); - cc.na--; /** do not count last expression (unknown number of elements) */ - } - else { - if (cc.v.k != LexState.VVOID) - this.exp2nextreg(cc.v); - this.setlist(cc.t.u.s.info, cc.na, cc.tostore); - } - } - - - - // ============================================================= - // from lcode.c - // ============================================================= - - void nil(int from, int n) { - InstructionPtr previous; - if (this.pc > this.lasttarget) { /* no jumps to current position? */ - if (this.pc == 0) { /* function start? */ - if (from >= this.nactvar) - return; /* positions are already clean */ - } else { - previous = new InstructionPtr(this.f.code, this.pc - 1); - if (GET_OPCODE(previous.get()) == OP_LOADNIL) { - int pfrom = GETARG_A(previous.get()); - int pto = GETARG_B(previous.get()); - if (pfrom <= from && from <= pto + 1) { /* can connect both? */ - if (from + n - 1 > pto) - SETARG_B(previous, from + n - 1); - return; - } - } - } - } - /* else no optimization */ - this.codeABC(OP_LOADNIL, from, from + n - 1, 0); - } - - - int jump() { - int jpc = this.jpc.i; /* save list of jumps to here */ - this.jpc.i = LexState.NO_JUMP; - IntPtr j = new IntPtr(this.codeAsBx(OP_JMP, 0, LexState.NO_JUMP)); - this.concat(j, jpc); /* keep them on hold */ - return j.i; - } - - void ret(int first, int nret) { - this.codeABC(OP_RETURN, first, nret + 1, 0); - } - - int condjump(int /* OpCode */op, int A, int B, int C) { - this.codeABC(op, A, B, C); - return this.jump(); - } - - void fixjump(int pc, int dest) { - InstructionPtr jmp = new InstructionPtr(this.f.code, pc); - int offset = dest - (pc + 1); - _assert (dest != LexState.NO_JUMP); - if (Math.abs(offset) > MAXARG_sBx) - ls.syntaxerror("control structure too long"); - SETARG_sBx(jmp, offset); - } - - - /* - * * returns current `pc' and marks it as a jump target (to avoid wrong * - * optimizations with consecutive instructions not in the same basic block). - */ - int getlabel() { - this.lasttarget = this.pc; - return this.pc; - } - - - int getjump(int pc) { - int offset = GETARG_sBx(this.f.code[pc]); - /* point to itself represents end of list */ - if (offset == LexState.NO_JUMP) - /* end of list */ - return LexState.NO_JUMP; - else - /* turn offset into absolute position */ - return (pc + 1) + offset; - } - - - InstructionPtr getjumpcontrol(int pc) { - InstructionPtr pi = new InstructionPtr(this.f.code, pc); - if (pc >= 1 && testTMode(GET_OPCODE(pi.code[pi.idx - 1]))) - return new InstructionPtr(pi.code, pi.idx - 1); - else - return pi; - } - - - /* - * * check whether list has any jump that do not produce a value * (or - * produce an inverted value) - */ - boolean need_value(int list) { - for (; list != LexState.NO_JUMP; list = this.getjump(list)) { - int i = this.getjumpcontrol(list).get(); - if (GET_OPCODE(i) != OP_TESTSET) - return true; - } - return false; /* not found */ - } - - - boolean patchtestreg(int node, int reg) { - InstructionPtr i = this.getjumpcontrol(node); - if (GET_OPCODE(i.get()) != OP_TESTSET) - /* cannot patch other instructions */ - return false; - if (reg != NO_REG && reg != GETARG_B(i.get())) - SETARG_A(i, reg); - else - /* no register to put value or register already has the value */ - i.set(CREATE_ABC(OP_TEST, GETARG_B(i.get()), 0, Lua.GETARG_C(i.get()))); - - return true; - } - - - void removevalues(int list) { - for (; list != LexState.NO_JUMP; list = this.getjump(list)) - this.patchtestreg(list, NO_REG); - } - - void patchlistaux(int list, int vtarget, int reg, int dtarget) { - while (list != LexState.NO_JUMP) { - int next = this.getjump(list); - if (this.patchtestreg(list, reg)) - this.fixjump(list, vtarget); - else - this.fixjump(list, dtarget); /* jump to default target */ - list = next; - } - } - - void dischargejpc() { - this.patchlistaux(this.jpc.i, this.pc, NO_REG, this.pc); - this.jpc.i = LexState.NO_JUMP; - } - - void patchlist(int list, int target) { - if (target == this.pc) - this.patchtohere(list); - else { - _assert (target < this.pc); - this.patchlistaux(list, target, NO_REG, target); - } - } - - void patchtohere(int list) { - this.getlabel(); - this.concat(this.jpc, list); - } - - void concat(IntPtr l1, int l2) { - if (l2 == LexState.NO_JUMP) - return; - if (l1.i == LexState.NO_JUMP) - l1.i = l2; - else { - int list = l1.i; - int next; - while ((next = this.getjump(list)) != LexState.NO_JUMP) - /* find last element */ - list = next; - this.fixjump(list, l2); - } - } - - void checkstack(int n) { - int newstack = this.freereg + n; - if (newstack > this.f.maxstacksize) { - if (newstack >= MAXSTACK) - ls.syntaxerror("function or expression too complex"); - this.f.maxstacksize = newstack; - } - } - - void reserveregs(int n) { - this.checkstack(n); - this.freereg += n; - } - - void freereg(int reg) { - if (!ISK(reg) && reg >= this.nactvar) { - this.freereg--; - _assert (reg == this.freereg); - } - } - - void freeexp(expdesc e) { - if (e.k == LexState.VNONRELOC) - this.freereg(e.u.s.info); - } - - int addk(LValue v) { - int idx; - if (this.htable.containsKey(v)) { - idx = ((Integer) htable.get(v)).intValue(); - } else { - idx = this.nk; - this.htable.put(v, new Integer(idx)); - final LPrototype f = this.f; - if (f.k == null || nk + 1 >= f.k.length) - f.k = realloc( f.k, nk*2 + 1 ); - f.k[this.nk++] = v; - } - return idx; - } - - int stringK(LString s) { - return this.addk(s); - } - - int numberK(LNumber r) { - if ( r instanceof LDouble ) { - double d = r.toJavaDouble(); - int i = (int) d; - if ( d == (double) i ) - r = LInteger.valueOf(i); - } - return this.addk(r); - } - - int boolK(boolean b) { - return this.addk((b ? LBoolean.TRUE : LBoolean.FALSE)); - } - - int nilK() { - return this.addk(LNil.NIL); - } - - void setreturns(expdesc e, int nresults) { - if (e.k == LexState.VCALL) { /* expression is an open function call? */ - SETARG_C(this.getcodePtr(e), nresults + 1); - } else if (e.k == LexState.VVARARG) { - SETARG_B(this.getcodePtr(e), nresults + 1); - SETARG_A(this.getcodePtr(e), this.freereg); - this.reserveregs(1); - } - } - - void setoneret(expdesc e) { - if (e.k == LexState.VCALL) { /* expression is an open function call? */ - e.k = LexState.VNONRELOC; - e.u.s.info = GETARG_A(this.getcode(e)); - } else if (e.k == LexState.VVARARG) { - SETARG_B(this.getcodePtr(e), 2); - e.k = LexState.VRELOCABLE; /* can relocate its simple result */ - } - } - - void dischargevars(expdesc e) { - switch (e.k) { - case LexState.VLOCAL: { - e.k = LexState.VNONRELOC; - break; - } - case LexState.VUPVAL: { - e.u.s.info = this.codeABC(OP_GETUPVAL, 0, e.u.s.info, 0); - e.k = LexState.VRELOCABLE; - break; - } - case LexState.VGLOBAL: { - e.u.s.info = this.codeABx(OP_GETGLOBAL, 0, e.u.s.info); - e.k = LexState.VRELOCABLE; - break; - } - case LexState.VINDEXED: { - this.freereg(e.u.s.aux); - this.freereg(e.u.s.info); - e.u.s.info = this - .codeABC(OP_GETTABLE, 0, e.u.s.info, e.u.s.aux); - e.k = LexState.VRELOCABLE; - break; - } - case LexState.VVARARG: - case LexState.VCALL: { - this.setoneret(e); - break; - } - default: - break; /* there is one value available (somewhere) */ - } - } - - int code_label(int A, int b, int jump) { - this.getlabel(); /* those instructions may be jump targets */ - return this.codeABC(OP_LOADBOOL, A, b, jump); - } - - void discharge2reg(expdesc e, int reg) { - this.dischargevars(e); - switch (e.k) { - case LexState.VNIL: { - this.nil(reg, 1); - break; - } - case LexState.VFALSE: - case LexState.VTRUE: { - this.codeABC(OP_LOADBOOL, reg, (e.k == LexState.VTRUE ? 1 : 0), - 0); - break; - } - case LexState.VK: { - this.codeABx(OP_LOADK, reg, e.u.s.info); - break; - } - case LexState.VKNUM: { - this.codeABx(OP_LOADK, reg, this.numberK(e.u.nval())); - break; - } - case LexState.VRELOCABLE: { - InstructionPtr pc = this.getcodePtr(e); - SETARG_A(pc, reg); - break; - } - case LexState.VNONRELOC: { - if (reg != e.u.s.info) - this.codeABC(OP_MOVE, reg, e.u.s.info, 0); - break; - } - default: { - _assert (e.k == LexState.VVOID || e.k == LexState.VJMP); - return; /* nothing to do... */ - } - } - e.u.s.info = reg; - e.k = LexState.VNONRELOC; - } - - void discharge2anyreg(expdesc e) { - if (e.k != LexState.VNONRELOC) { - this.reserveregs(1); - this.discharge2reg(e, this.freereg - 1); - } - } - - void exp2reg(expdesc e, int reg) { - this.discharge2reg(e, reg); - if (e.k == LexState.VJMP) - this.concat(e.t, e.u.s.info); /* put this jump in `t' list */ - if (e.hasjumps()) { - int _final; /* position after whole expression */ - int p_f = LexState.NO_JUMP; /* position of an eventual LOAD false */ - int p_t = LexState.NO_JUMP; /* position of an eventual LOAD true */ - if (this.need_value(e.t.i) || this.need_value(e.f.i)) { - int fj = (e.k == LexState.VJMP) ? LexState.NO_JUMP : this - .jump(); - p_f = this.code_label(reg, 0, 1); - p_t = this.code_label(reg, 1, 0); - this.patchtohere(fj); - } - _final = this.getlabel(); - this.patchlistaux(e.f.i, _final, reg, p_f); - this.patchlistaux(e.t.i, _final, reg, p_t); - } - e.f.i = e.t.i = LexState.NO_JUMP; - e.u.s.info = reg; - e.k = LexState.VNONRELOC; - } - - void exp2nextreg(expdesc e) { - this.dischargevars(e); - this.freeexp(e); - this.reserveregs(1); - this.exp2reg(e, this.freereg - 1); - } - - int exp2anyreg(expdesc e) { - this.dischargevars(e); - if (e.k == LexState.VNONRELOC) { - if (!e.hasjumps()) - return e.u.s.info; /* exp is already in a register */ - if (e.u.s.info >= this.nactvar) { /* reg. is not a local? */ - this.exp2reg(e, e.u.s.info); /* put value on it */ - return e.u.s.info; - } - } - this.exp2nextreg(e); /* default */ - return e.u.s.info; - } - - void exp2val(expdesc e) { - if (e.hasjumps()) - this.exp2anyreg(e); - else - this.dischargevars(e); - } - - int exp2RK(expdesc e) { - this.exp2val(e); - switch (e.k) { - case LexState.VKNUM: - case LexState.VTRUE: - case LexState.VFALSE: - case LexState.VNIL: { - if (this.nk <= MAXINDEXRK) { /* constant fit in RK operand? */ - e.u.s.info = (e.k == LexState.VNIL) ? this.nilK() - : (e.k == LexState.VKNUM) ? this.numberK(e.u.nval()) - : this.boolK((e.k == LexState.VTRUE)); - e.k = LexState.VK; - return RKASK(e.u.s.info); - } else - break; - } - case LexState.VK: { - if (e.u.s.info <= MAXINDEXRK) /* constant fit in argC? */ - return RKASK(e.u.s.info); - else - break; - } - default: - break; - } - /* not a constant in the right range: put it in a register */ - return this.exp2anyreg(e); - } - - void storevar(expdesc var, expdesc ex) { - switch (var.k) { - case LexState.VLOCAL: { - this.freeexp(ex); - this.exp2reg(ex, var.u.s.info); - return; - } - case LexState.VUPVAL: { - int e = this.exp2anyreg(ex); - this.codeABC(OP_SETUPVAL, e, var.u.s.info, 0); - break; - } - case LexState.VGLOBAL: { - int e = this.exp2anyreg(ex); - this.codeABx(OP_SETGLOBAL, e, var.u.s.info); - break; - } - case LexState.VINDEXED: { - int e = this.exp2RK(ex); - this.codeABC(OP_SETTABLE, var.u.s.info, var.u.s.aux, e); - break; - } - default: { - _assert (false); /* invalid var kind to store */ - break; - } - } - this.freeexp(ex); - } - - void self(expdesc e, expdesc key) { - int func; - this.exp2anyreg(e); - this.freeexp(e); - func = this.freereg; - this.reserveregs(2); - this.codeABC(OP_SELF, func, e.u.s.info, this.exp2RK(key)); - this.freeexp(key); - e.u.s.info = func; - e.k = LexState.VNONRELOC; - } - - void invertjump(expdesc e) { - InstructionPtr pc = this.getjumpcontrol(e.u.s.info); - _assert (testTMode(GET_OPCODE(pc.get())) - && GET_OPCODE(pc.get()) != OP_TESTSET && Lua - .GET_OPCODE(pc.get()) != OP_TEST); - // SETARG_A(pc, !(GETARG_A(pc.get()))); - int a = GETARG_A(pc.get()); - int nota = (a!=0? 0: 1); - SETARG_A(pc, nota); - } - - int jumponcond(expdesc e, int cond) { - if (e.k == LexState.VRELOCABLE) { - int ie = this.getcode(e); - if (GET_OPCODE(ie) == OP_NOT) { - this.pc--; /* remove previous OP_NOT */ - return this.condjump(OP_TEST, GETARG_B(ie), 0, (cond!=0? 0: 1)); - } - /* else go through */ - } - this.discharge2anyreg(e); - this.freeexp(e); - return this.condjump(OP_TESTSET, NO_REG, e.u.s.info, cond); - } - - void goiftrue(expdesc e) { - int pc; /* pc of last jump */ - this.dischargevars(e); - switch (e.k) { - case LexState.VK: - case LexState.VKNUM: - case LexState.VTRUE: { - pc = LexState.NO_JUMP; /* always true; do nothing */ - break; - } - case LexState.VFALSE: { - pc = this.jump(); /* always jump */ - break; - } - case LexState.VJMP: { - this.invertjump(e); - pc = e.u.s.info; - break; - } - default: { - pc = this.jumponcond(e, 0); - break; - } - } - this.concat(e.f, pc); /* insert last jump in `f' list */ - this.patchtohere(e.t.i); - e.t.i = LexState.NO_JUMP; - } - - void goiffalse(expdesc e) { - int pc; /* pc of last jump */ - this.dischargevars(e); - switch (e.k) { - case LexState.VNIL: - case LexState.VFALSE: { - pc = LexState.NO_JUMP; /* always false; do nothing */ - break; - } - case LexState.VTRUE: { - pc = this.jump(); /* always jump */ - break; - } - case LexState.VJMP: { - pc = e.u.s.info; - break; - } - default: { - pc = this.jumponcond(e, 1); - break; - } - } - this.concat(e.t, pc); /* insert last jump in `t' list */ - this.patchtohere(e.f.i); - e.f.i = LexState.NO_JUMP; - } - - void codenot(expdesc e) { - this.dischargevars(e); - switch (e.k) { - case LexState.VNIL: - case LexState.VFALSE: { - e.k = LexState.VTRUE; - break; - } - case LexState.VK: - case LexState.VKNUM: - case LexState.VTRUE: { - e.k = LexState.VFALSE; - break; - } - case LexState.VJMP: { - this.invertjump(e); - break; - } - case LexState.VRELOCABLE: - case LexState.VNONRELOC: { - this.discharge2anyreg(e); - this.freeexp(e); - e.u.s.info = this.codeABC(OP_NOT, 0, e.u.s.info, 0); - e.k = LexState.VRELOCABLE; - break; - } - default: { - _assert (false); /* cannot happen */ - break; - } - } - /* interchange true and false lists */ - { - int temp = e.f.i; - e.f.i = e.t.i; - e.t.i = temp; - } - this.removevalues(e.f.i); - this.removevalues(e.t.i); - } - - void indexed(expdesc t, expdesc k) { - t.u.s.aux = this.exp2RK(k); - t.k = LexState.VINDEXED; - } - - boolean constfolding(int op, expdesc e1, expdesc e2) { - LNumber v1, v2, r; - if (!e1.isnumeral() || !e2.isnumeral()) - return false; - v1 = e1.u.nval(); - v2 = e2.u.nval(); - switch (op) { - case OP_ADD: - case OP_SUB: - case OP_MUL: - case OP_DIV: - case OP_MOD: - r = (LNumber) v2.luaBinOpUnknown(op, v1); - break; - case OP_POW: - r = Platform.getInstance().mathPow( v1, v2 ); - break; - case OP_UNM: - r = (LNumber) v1.luaUnaryMinus(); - break; - case OP_LEN: - return false; /* no constant folding for 'len' */ - default: - _assert (false); - r = null; - break; - } - if (Double.NaN == r.toJavaDouble()) - return false; /* do not attempt to produce NaN */ - e1.u.setNval( r ); - return true; - } - - void codearith(int op, expdesc e1, expdesc e2) { - if (constfolding(op, e1, e2)) - return; - else { - int o2 = (op != OP_UNM && op != OP_LEN) ? this.exp2RK(e2) - : 0; - int o1 = this.exp2RK(e1); - if (o1 > o2) { - this.freeexp(e1); - this.freeexp(e2); - } else { - this.freeexp(e2); - this.freeexp(e1); - } - e1.u.s.info = this.codeABC(op, 0, o1, o2); - e1.k = LexState.VRELOCABLE; - } - } - - void codecomp(int /* OpCode */op, int cond, expdesc e1, expdesc e2) { - int o1 = this.exp2RK(e1); - int o2 = this.exp2RK(e2); - this.freeexp(e2); - this.freeexp(e1); - if (cond == 0 && op != OP_EQ) { - int temp; /* exchange args to replace by `<' or `<=' */ - temp = o1; - o1 = o2; - o2 = temp; /* o1 <==> o2 */ - cond = 1; - } - e1.u.s.info = this.condjump(op, cond, o1, o2); - e1.k = LexState.VJMP; - } - - void prefix(int /* UnOpr */op, expdesc e) { - expdesc e2 = new expdesc(); - e2.init(LexState.VKNUM, 0); - switch (op) { - case LexState.OPR_MINUS: { - if (e.k == LexState.VK) - this.exp2anyreg(e); /* cannot operate on non-numeric constants */ - this.codearith(OP_UNM, e, e2); - break; - } - case LexState.OPR_NOT: - this.codenot(e); - break; - case LexState.OPR_LEN: { - this.exp2anyreg(e); /* cannot operate on constants */ - this.codearith(OP_LEN, e, e2); - break; - } - default: - _assert (false); - } - } - - void infix(int /* BinOpr */op, expdesc v) { - switch (op) { - case LexState.OPR_AND: { - this.goiftrue(v); - break; - } - case LexState.OPR_OR: { - this.goiffalse(v); - break; - } - case LexState.OPR_CONCAT: { - this.exp2nextreg(v); /* operand must be on the `stack' */ - break; - } - case LexState.OPR_ADD: - case LexState.OPR_SUB: - case LexState.OPR_MUL: - case LexState.OPR_DIV: - case LexState.OPR_MOD: - case LexState.OPR_POW: { - if (!v.isnumeral()) - this.exp2RK(v); - break; - } - default: { - this.exp2RK(v); - break; - } - } - } - - - void posfix(int op, expdesc e1, expdesc e2) { - switch (op) { - case LexState.OPR_AND: { - _assert (e1.t.i == LexState.NO_JUMP); /* list must be closed */ - this.dischargevars(e2); - this.concat(e2.f, e1.f.i); - // *e1 = *e2; - e1.setvalue(e2); - break; - } - case LexState.OPR_OR: { - _assert (e1.f.i == LexState.NO_JUMP); /* list must be closed */ - this.dischargevars(e2); - this.concat(e2.t, e1.t.i); - // *e1 = *e2; - e1.setvalue(e2); - break; - } - case LexState.OPR_CONCAT: { - this.exp2val(e2); - if (e2.k == LexState.VRELOCABLE - && GET_OPCODE(this.getcode(e2)) == OP_CONCAT) { - _assert (e1.u.s.info == GETARG_B(this.getcode(e2)) - 1); - this.freeexp(e1); - SETARG_B(this.getcodePtr(e2), e1.u.s.info); - e1.k = LexState.VRELOCABLE; - e1.u.s.info = e2.u.s.info; - } else { - this.exp2nextreg(e2); /* operand must be on the 'stack' */ - this.codearith(OP_CONCAT, e1, e2); - } - break; - } - case LexState.OPR_ADD: - this.codearith(OP_ADD, e1, e2); - break; - case LexState.OPR_SUB: - this.codearith(OP_SUB, e1, e2); - break; - case LexState.OPR_MUL: - this.codearith(OP_MUL, e1, e2); - break; - case LexState.OPR_DIV: - this.codearith(OP_DIV, e1, e2); - break; - case LexState.OPR_MOD: - this.codearith(OP_MOD, e1, e2); - break; - case LexState.OPR_POW: - this.codearith(OP_POW, e1, e2); - break; - case LexState.OPR_EQ: - this.codecomp(OP_EQ, 1, e1, e2); - break; - case LexState.OPR_NE: - this.codecomp(OP_EQ, 0, e1, e2); - break; - case LexState.OPR_LT: - this.codecomp(OP_LT, 1, e1, e2); - break; - case LexState.OPR_LE: - this.codecomp(OP_LE, 1, e1, e2); - break; - case LexState.OPR_GT: - this.codecomp(OP_LT, 0, e1, e2); - break; - case LexState.OPR_GE: - this.codecomp(OP_LE, 0, e1, e2); - break; - default: - _assert (false); - } - } - - - void fixline(int line) { - this.f.lineinfo[this.pc - 1] = line; - } - - - int code(int instruction, int line) { - LPrototype f = this.f; - this.dischargejpc(); /* `pc' will change */ - /* put new instruction in code array */ - if (f.code == null || this.pc + 1 > f.code.length) - f.code = LuaC.realloc(f.code, this.pc * 2 + 1); - f.code[this.pc] = instruction; - /* save corresponding line information */ - if (f.lineinfo == null || this.pc + 1 > f.lineinfo.length) - f.lineinfo = LuaC.realloc(f.lineinfo, - this.pc * 2 + 1); - f.lineinfo[this.pc] = line; - return this.pc++; - } - - - int codeABC(int o, int a, int b, int c) { - _assert (getOpMode(o) == iABC); - _assert (getBMode(o) != OpArgN || b == 0); - _assert (getCMode(o) != OpArgN || c == 0); - return this.code(CREATE_ABC(o, a, b, c), this.ls.lastline); - } - - - int codeABx(int o, int a, int bc) { - _assert (getOpMode(o) == iABx || getOpMode(o) == iAsBx); - _assert (getCMode(o) == OpArgN); - return this.code(CREATE_ABx(o, a, bc), this.ls.lastline); - } - - - void setlist(int base, int nelems, int tostore) { - int c = (nelems - 1) / LFIELDS_PER_FLUSH + 1; - int b = (tostore == LUA_MULTRET) ? 0 : tostore; - _assert (tostore != 0); - if (c <= MAXARG_C) - this.codeABC(OP_SETLIST, base, b, c); - else { - this.codeABC(OP_SETLIST, base, b, 0); - this.code(c, this.ls.lastline); - } - this.freereg = base + 1; /* free registers with list values */ - } - -} diff --git a/src/core/org/luaj/compiler/InstructionPtr.java b/src/core/org/luaj/compiler/InstructionPtr.java deleted file mode 100644 index 4393eba8..00000000 --- a/src/core/org/luaj/compiler/InstructionPtr.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.compiler; - -class InstructionPtr { - final int[] code; - final int idx; - InstructionPtr(int[] code, int idx ) { - this.code = code; - this.idx = idx; - } - int get() { - return code[idx]; - } - void set(int value) { - code[idx] = value; - } -} \ No newline at end of file diff --git a/src/core/org/luaj/compiler/IntPtr.java b/src/core/org/luaj/compiler/IntPtr.java deleted file mode 100644 index f196e1ff..00000000 --- a/src/core/org/luaj/compiler/IntPtr.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.compiler; - -public class IntPtr { - int i; - IntPtr() { - } - IntPtr(int value) { - this.i = value; - } -} diff --git a/src/core/org/luaj/compiler/LexState.java b/src/core/org/luaj/compiler/LexState.java deleted file mode 100644 index 41331d42..00000000 --- a/src/core/org/luaj/compiler/LexState.java +++ /dev/null @@ -1,1904 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.compiler; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Hashtable; - -import org.luaj.compiler.FuncState.BlockCnt; -import org.luaj.vm.LDouble; -import org.luaj.vm.LInteger; -import org.luaj.vm.LNumber; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LString; -import org.luaj.vm.LocVars; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaErrorException; - - -public class LexState { - - protected static final String RESERVED_LOCAL_VAR_FOR_CONTROL = "(for control)"; - protected static final String RESERVED_LOCAL_VAR_FOR_STATE = "(for state)"; - protected static final String RESERVED_LOCAL_VAR_FOR_GENERATOR = "(for generator)"; - protected static final String RESERVED_LOCAL_VAR_FOR_STEP = "(for step)"; - protected static final String RESERVED_LOCAL_VAR_FOR_LIMIT = "(for limit)"; - protected static final String RESERVED_LOCAL_VAR_FOR_INDEX = "(for index)"; - - // keywords array - protected static final String[] RESERVED_LOCAL_VAR_KEYWORDS = new String[] { - RESERVED_LOCAL_VAR_FOR_CONTROL, - RESERVED_LOCAL_VAR_FOR_GENERATOR, - RESERVED_LOCAL_VAR_FOR_INDEX, - RESERVED_LOCAL_VAR_FOR_LIMIT, - RESERVED_LOCAL_VAR_FOR_STATE, - RESERVED_LOCAL_VAR_FOR_STEP - }; - private static final Hashtable RESERVED_LOCAL_VAR_KEYWORDS_TABLE = new Hashtable(); - static { - for ( int i=0; i=", "<=", "~=", - "", "", "", "", - }; - - final static int - /* terminal symbols denoted by reserved words */ - TK_AND=257, TK_BREAK=258, TK_DO=259, TK_ELSE=260, TK_ELSEIF=261, - TK_END=262, TK_FALSE=263, TK_FOR=264, TK_FUNCTION=265, TK_IF=266, - TK_IN=267, TK_LOCAL=268, TK_NIL=269, TK_NOT=270, TK_OR=271, TK_REPEAT=272, - TK_RETURN=273, TK_THEN=274, TK_TRUE=275, TK_UNTIL=276, TK_WHILE=277, - /* other terminal symbols */ - TK_CONCAT=278, TK_DOTS=279, TK_EQ=280, TK_GE=281, TK_LE=282, TK_NE=283, - TK_NUMBER=284, TK_NAME=285, TK_STRING=286, TK_EOS=287; - - final static int FIRST_RESERVED = TK_AND; - final static int NUM_RESERVED = TK_WHILE+1-FIRST_RESERVED; - - final static Hashtable RESERVED = new Hashtable(); - static { - for ( int i=0; i= '0' && c <= '9') - || (c >= 'a' && c <= 'z') - || (c >= 'A' && c <= 'Z') - || (c == '_'); - // return Character.isLetterOrDigit(c); - } - - private boolean isalpha(int c) { - return (c >= 'a' && c <= 'z') - || (c >= 'A' && c <= 'Z'); - } - - private boolean isdigit(int c) { - return (c >= '0' && c <= '9'); - } - - private boolean isspace(int c) { - return (c <= ' '); - } - - - public LexState(LuaC state, InputStream stream) { - this.z = stream; - this.buff = new byte[32]; - this.L = state; - } - - void nextChar() { - try { - current = z.read(); - } catch ( IOException e ) { - e.printStackTrace(); - current = EOZ; - } - } - - boolean currIsNewline() { - return current == '\n' || current == '\r'; - } - - void save_and_next() { - save( current ); - nextChar(); - } - - void save(int c) { - if ( buff == null || nbuff + 1 > buff.length ) - buff = LuaC.realloc( buff, nbuff*2+1 ); - buff[nbuff++] = (byte) c; - } - - - String token2str( int token ) { - if ( token < FIRST_RESERVED ) { - return iscntrl(token)? - L.pushfstring( "char("+((int)token)+")" ): - L.pushfstring( String.valueOf( (char) token ) ); - } else { - return luaX_tokens[token-FIRST_RESERVED]; - } - } - - private static boolean iscntrl(int token) { - return token < ' '; - } - - String txtToken(int token) { - switch ( token ) { - case TK_NAME: - case TK_STRING: - case TK_NUMBER: - return new String( buff, 0, nbuff ); - default: - return token2str( token ); - } - } - - void lexerror( String msg, int token ) { - String cid = chunkid( source.toString() ); // TODO: get source name from source - L.pushfstring( cid+":"+linenumber+": "+msg ); - if ( token != 0 ) - L.pushfstring( "syntax error: "+msg+" near "+txtToken(token) ); - throw new LuaErrorException(cid+":"+linenumber+": "+msg); - } - - String chunkid( String source ) { - if ( source.startsWith("=") ) - return source.substring(1); - String end = ""; - if ( source.startsWith("@") ) { - source = source.substring(1); - } else { - source = "[string \""+source; - end = "\"]"; - } - int n = source.length() + end.length(); - if ( n > MAXSRC ) - source = source.substring(0,MAXSRC-end.length()-3) + "..."; - return source + end; - } - - void syntaxerror( String msg ) { - lexerror( msg, t.token ); - } - - LString newstring( String s ) { - return L.newTString( LString.valueOf(s) ); - } - - LString newstring( byte[] chars, int offset, int len ) { - return L.newTString( LString.newStringNoCopy(chars, offset, len) ); - } - - void inclinenumber() { - int old = current; - LuaC._assert( currIsNewline() ); - nextChar(); /* skip '\n' or '\r' */ - if ( currIsNewline() && current != old ) - nextChar(); /* skip '\n\r' or '\r\n' */ - if ( ++linenumber >= MAX_INT ) - syntaxerror("chunk has too many lines"); - } - - void setinput( LuaC L, int firstByte, InputStream z, LString source ) { - this.decpoint = '.'; - this.L = L; - this.lookahead.token = TK_EOS; /* no look-ahead token */ - this.z = z; - this.fs = null; - this.linenumber = 1; - this.lastline = 1; - this.source = source; - this.nbuff = 0; /* initialize buffer */ - this.current = firstByte; /* read first char */ - this.skipShebang(); - } - - private void skipShebang() { - if ( current == '#' ) - while (!currIsNewline() && current != EOZ) - nextChar(); - } - - - - /* - ** ======================================================= - ** LEXICAL ANALYZER - ** ======================================================= - */ - - - boolean check_next(String set) { - if (set.indexOf(current) < 0) - return false; - save_and_next(); - return true; - } - - void buffreplace(byte from, byte to) { - int n = nbuff; - byte[] p = buff; - while ((--n) >= 0) - if (p[n] == from) - p[n] = to; - } - - boolean str2d(String str, SemInfo seminfo) { - double d; - str = str.trim(); // TODO: get rid of this - if ( str.startsWith("0x") ) { - d = Long.parseLong(str.substring(2), 16); - } - else - d = Double.parseDouble(str); - seminfo.r = LDouble.numberOf(d); - return true; - } - - // - // TODO: reexamine this source and see if it should be ported differently - // - // static void trydecpoint (LexState *ls, SemInfo *seminfo) { - // /* format error: try to update decimal point separator */ - // struct lconv *cv = localeconv(); - // char old = this.decpoint; - // this.decpoint = (cv ? cv->decimal_point[0] : '.'); - // buffreplace(ls, old, this.decpoint); /* try updated decimal separator */ - // if (!luaO_str2d(luaZ_buffer(this.buff), &seminfo->r)) { - // /* format error with correct decimal point: no more options */ - // buffreplace(ls, this.decpoint, '.'); /* undo change (for error message) */ - // luaX_lexerror(ls, "malformed number", TK_NUMBER); - // } - // } - // - /* - void trydecpoint(String str, SemInfo seminfo) { - NumberFormat nf = NumberFormat.getInstance(); - try { - Number n = nf.parse(str); - double d = n.doubleValue(); - seminfo.r = new LDouble(d); - } catch (ParseException e) { - lexerror("malformed number", TK_NUMBER); - } - } - */ - - void read_numeral(SemInfo seminfo) { - LuaC._assert (isdigit(current)); - do { - save_and_next(); - } while (isdigit(current) || current == '.'); - if (check_next("Ee")) /* `E'? */ - check_next("+-"); /* optional exponent sign */ - while (isalnum(current) || current == '_') - save_and_next(); - save('\0'); - buffreplace((byte)'.', decpoint); /* follow locale for decimal point */ - String str = new String(buff, 0, nbuff); -// if (!str2d(str, seminfo)) /* format error? */ -// trydecpoint(str, seminfo); /* try to update decimal point separator */ - str2d(str, seminfo); - } - - int skip_sep() { - int count = 0; - int s = current; - LuaC._assert (s == '[' || s == ']'); - save_and_next(); - while (current == '=') { - save_and_next(); - count++; - } - return (current == s) ? count : (-count) - 1; - } - - void read_long_string(SemInfo seminfo, int sep) { - int cont = 0; - save_and_next(); /* skip 2nd `[' */ - if (currIsNewline()) /* string starts with a newline? */ - inclinenumber(); /* skip it */ - for (boolean endloop = false; !endloop;) { - switch (current) { - case EOZ: - lexerror((seminfo != null) ? "unfinished long string" - : "unfinished long comment", TK_EOS); - break; /* to avoid warnings */ - case '[': { - if (skip_sep() == sep) { - save_and_next(); /* skip 2nd `[' */ - cont++; - if (LUA_COMPAT_LSTR == 1) { - if (sep == 0) - lexerror("nesting of [[...]] is deprecated", '['); - } - } - break; - } - case ']': { - if (skip_sep() == sep) { - save_and_next(); /* skip 2nd `]' */ - if (LUA_COMPAT_LSTR == 2) { - cont--; - if (sep == 0 && cont >= 0) - break; - } - endloop = true; - } - break; - } - case '\n': - case '\r': { - save('\n'); - inclinenumber(); - if (seminfo == null) - nbuff = 0; /* avoid wasting space */ - break; - } - default: { - if (seminfo != null) - save_and_next(); - else - nextChar(); - } - } - } - if (seminfo != null) - seminfo.ts = newstring(buff, 2 + sep, nbuff - 2 * (2 + sep)); - } - - void read_string(int del, SemInfo seminfo) { - save_and_next(); - while (current != del) { - switch (current) { - case EOZ: - lexerror("unfinished string", TK_EOS); - continue; /* to avoid warnings */ - case '\n': - case '\r': - lexerror("unfinished string", TK_STRING); - continue; /* to avoid warnings */ - case '\\': { - int c; - nextChar(); /* do not save the `\' */ - switch (current) { - case 'a': /* bell */ - c = '\u0007'; - break; - case 'b': /* backspace */ - c = '\b'; - break; - case 'f': /* form feed */ - c = '\f'; - break; - case 'n': /* newline */ - c = '\n'; - break; - case 'r': /* carriage return */ - c = '\r'; - break; - case 't': /* tab */ - c = '\t'; - break; - case 'v': /* vertical tab */ - c = '\u000B'; - break; - case '\n': /* go through */ - case '\r': - save('\n'); - inclinenumber(); - continue; - case EOZ: - continue; /* will raise an error next loop */ - default: { - if (!isdigit(current)) - save_and_next(); /* handles \\, \", \', and \? */ - else { /* \xxx */ - int i = 0; - c = 0; - do { - c = 10 * c + (current - '0'); - nextChar(); - } while (++i < 3 && isdigit(current)); - if (c > UCHAR_MAX) - lexerror("escape sequence too large", TK_STRING); - save(c); - } - continue; - } - } - save(c); - nextChar(); - continue; - } - default: - save_and_next(); - } - } - save_and_next(); /* skip delimiter */ - seminfo.ts = newstring(buff, 1, nbuff - 2); - } - - int llex(SemInfo seminfo) { - nbuff = 0; - while (true) { - switch (current) { - case '\n': - case '\r': { - inclinenumber(); - continue; - } - case '-': { - nextChar(); - if (current != '-') - return '-'; - /* else is a comment */ - nextChar(); - if (current == '[') { - int sep = skip_sep(); - nbuff = 0; /* `skip_sep' may dirty the buffer */ - if (sep >= 0) { - read_long_string(null, sep); /* long comment */ - nbuff = 0; - continue; - } - } - /* else short comment */ - while (!currIsNewline() && current != EOZ) - nextChar(); - continue; - } - case '[': { - int sep = skip_sep(); - if (sep >= 0) { - read_long_string(seminfo, sep); - return TK_STRING; - } else if (sep == -1) - return '['; - else - lexerror("invalid long string delimiter", TK_STRING); - } - case '=': { - nextChar(); - if (current != '=') - return '='; - else { - nextChar(); - return TK_EQ; - } - } - case '<': { - nextChar(); - if (current != '=') - return '<'; - else { - nextChar(); - return TK_LE; - } - } - case '>': { - nextChar(); - if (current != '=') - return '>'; - else { - nextChar(); - return TK_GE; - } - } - case '~': { - nextChar(); - if (current != '=') - return '~'; - else { - nextChar(); - return TK_NE; - } - } - case '"': - case '\'': { - read_string(current, seminfo); - return TK_STRING; - } - case '.': { - save_and_next(); - if (check_next(".")) { - if (check_next(".")) - return TK_DOTS; /* ... */ - else - return TK_CONCAT; /* .. */ - } else if (!isdigit(current)) - return '.'; - else { - read_numeral(seminfo); - return TK_NUMBER; - } - } - case EOZ: { - return TK_EOS; - } - default: { - if (isspace(current)) { - LuaC._assert (!currIsNewline()); - nextChar(); - continue; - } else if (isdigit(current)) { - read_numeral(seminfo); - return TK_NUMBER; - } else if (isalpha(current) || current == '_') { - /* identifier or reserved word */ - LString ts; - do { - save_and_next(); - } while (isalnum(current) || current == '_'); - ts = newstring(buff, 0, nbuff); - if ( RESERVED.containsKey(ts) ) - return ((Integer)RESERVED.get(ts)).intValue(); - else { - seminfo.ts = ts; - return TK_NAME; - } - } else { - int c = current; - nextChar(); - return c; /* single-char tokens (+ - / ...) */ - } - } - } - } - } - - void next() { - lastline = linenumber; - if (lookahead.token != TK_EOS) { /* is there a look-ahead token? */ - t.set( lookahead ); /* use this one */ - lookahead.token = TK_EOS; /* and discharge it */ - } else - t.token = llex(t.seminfo); /* read next token */ - } - - void lookahead() { - LuaC._assert (lookahead.token == TK_EOS); - lookahead.token = llex(lookahead.seminfo); - } - - // ============================================================= - // from lcode.h - // ============================================================= - - - // ============================================================= - // from lparser.c - // ============================================================= - - static class expdesc { - int k; // expkind, from enumerated list, above - static class U { // originally a union - static class S { - int info, aux; - } - final S s = new S(); - private LNumber _nval; - public void setNval(LNumber r) { - _nval = r; - } - public LNumber nval() { - return (_nval == null? LInteger.valueOf(s.info): _nval); - } - }; - final U u = new U(); - final IntPtr t = new IntPtr(); /* patch list of `exit when true' */ - final IntPtr f = new IntPtr(); /* patch list of `exit when false' */ - void init( int k, int i ) { - this.f.i = NO_JUMP; - this.t.i = NO_JUMP; - this.k = k; - this.u.s.info = i; - } - - boolean hasjumps() { - return (t.i != f.i); - } - - boolean isnumeral() { - return (k == VKNUM && t.i == NO_JUMP && f.i == NO_JUMP); - } - - public void setvalue(expdesc other) { - this.k = other.k; - this.u._nval = other.u._nval; - this.u.s.info = other.u.s.info; - this.u.s.aux = other.u.s.aux; - this.t.i = other.t.i; - this.f.i = other.f.i; - } - } - - boolean hasmultret(int k) { - return ((k) == VCALL || (k) == VVARARG); - } - - /*---------------------------------------------------------------------- - name args description - ------------------------------------------------------------------------*/ - - /* - * * prototypes for recursive non-terminal functions - */ - - void error_expected(int token) { - syntaxerror(L.pushfstring(LUA_QS(token2str(token)) + " expected")); - } - - boolean testnext(int c) { - if (t.token == c) { - next(); - return true; - } else - return false; - } - - void check(int c) { - if (t.token != c) - error_expected(c); - } - - void checknext (int c) { - check(c); - next(); - } - - void check_condition(boolean c, String msg) { - if (!(c)) - syntaxerror(msg); - } - - - void check_match(int what, int who, int where) { - if (!testnext(what)) { - if (where == linenumber) - error_expected(what); - else { - syntaxerror(L.pushfstring(LUA_QS(token2str(what)) - + " expected " + "(to close " + LUA_QS(token2str(who)) - + " at line " + where + ")")); - } - } - } - - LString str_checkname() { - LString ts; - check(TK_NAME); - ts = t.seminfo.ts; - next(); - return ts; - } - - void codestring(expdesc e, LString s) { - e.init(VK, fs.stringK(s)); - } - - void checkname(expdesc e) { - codestring(e, str_checkname()); - } - - - int registerlocalvar(LString varname) { - FuncState fs = this.fs; - LPrototype f = fs.f; - if (f.locvars == null || fs.nlocvars + 1 > f.locvars.length) - f.locvars = LuaC.realloc( f.locvars, fs.nlocvars*2+1 ); - f.locvars[fs.nlocvars] = new LocVars(varname,0,0); - return fs.nlocvars++; - } - - -// -// #define new_localvarliteral(ls,v,n) \ -// this.new_localvar(luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) -// - void new_localvarliteral(String v, int n) { - LString ts = newstring(v); - new_localvar(ts, n); - } - - void new_localvar(LString name, int n) { - FuncState fs = this.fs; - fs.checklimit(fs.nactvar + n + 1, FuncState.LUAI_MAXVARS, "local variables"); - fs.actvar[fs.nactvar + n] = (short) registerlocalvar(name); - } - - void adjustlocalvars(int nvars) { - FuncState fs = this.fs; - fs.nactvar = (short) (fs.nactvar + nvars); - for (; nvars > 0; nvars--) { - fs.getlocvar(fs.nactvar - nvars).startpc = fs.pc; - } - } - - void removevars(int tolevel) { - FuncState fs = this.fs; - while (fs.nactvar > tolevel) - fs.getlocvar(--fs.nactvar).endpc = fs.pc; - } - - void singlevar(expdesc var) { - LString varname = this.str_checkname(); - FuncState fs = this.fs; - if (fs.singlevaraux(varname, var, 1) == VGLOBAL) - var.u.s.info = fs.stringK(varname); /* info points to global name */ - } - - void adjust_assign(int nvars, int nexps, expdesc e) { - FuncState fs = this.fs; - int extra = nvars - nexps; - if (hasmultret(e.k)) { - /* includes call itself */ - extra++; - if (extra < 0) - extra = 0; - /* last exp. provides the difference */ - fs.setreturns(e, extra); - if (extra > 1) - fs.reserveregs(extra - 1); - } else { - /* close last expression */ - if (e.k != VVOID) - fs.exp2nextreg(e); - if (extra > 0) { - int reg = fs.freereg; - fs.reserveregs(extra); - fs.nil(reg, extra); - } - } - } - - void enterlevel() { - if (++L.nCcalls > LUAI_MAXCCALLS) - lexerror("chunk has too many syntax levels", 0); - } - - void leavelevel() { - L.nCcalls--; - } - - void pushclosure(FuncState func, expdesc v) { - FuncState fs = this.fs; - LPrototype f = fs.f; - if (f.p == null || fs.np + 1 > f.p.length) - f.p = LuaC.realloc( f.p, fs.np*2 + 1 ); - f.p[fs.np++] = func.f; - v.init(VRELOCABLE, fs.codeABx(Lua.OP_CLOSURE, 0, fs.np - 1)); - for (int i = 0; i < func.f.nups; i++) { - int o = (func.upvalues[i].k == VLOCAL) ? Lua.OP_MOVE - : Lua.OP_GETUPVAL; - fs.codeABC(o, 0, func.upvalues[i].info, 0); - } - } - - void open_func (FuncState fs) { - LuaC L = this.L; - LPrototype f = new LPrototype(); - if ( this.fs!=null ) - f.source = this.fs.f.source; - fs.f = f; - fs.prev = this.fs; /* linked list of funcstates */ - fs.ls = this; - fs.L = L; - this.fs = fs; - fs.pc = 0; - fs.lasttarget = -1; - fs.jpc = new IntPtr( NO_JUMP ); - fs.freereg = 0; - fs.nk = 0; - fs.np = 0; - fs.nlocvars = 0; - fs.nactvar = 0; - fs.bl = null; - f.maxstacksize = 2; /* registers 0/1 are always valid */ - //fs.h = new LTable(); - fs.htable = new Hashtable(); - } - - void close_func() { - FuncState fs = this.fs; - LPrototype f = fs.f; - this.removevars(0); - fs.ret(0, 0); /* final return */ - f.code = LuaC.realloc(f.code, fs.pc); - f.lineinfo = LuaC.realloc(f.lineinfo, fs.pc); - // f.sizelineinfo = fs.pc; - f.k = LuaC.realloc(f.k, fs.nk); - f.p = LuaC.realloc(f.p, fs.np); - f.locvars = LuaC.realloc(f.locvars, fs.nlocvars); - // f.sizelocvars = fs.nlocvars; - f.upvalues = LuaC.realloc(f.upvalues, f.nups); - // LuaC._assert (CheckCode.checkcode(f)); - LuaC._assert (fs.bl == null); - this.fs = fs.prev; -// L.top -= 2; /* remove table and prototype from the stack */ - // /* last token read was anchored in defunct function; must reanchor it - // */ - // if (fs!=null) ls.anchor_token(); - } - - /*============================================================*/ - /* GRAMMAR RULES */ - /*============================================================*/ - - void field(expdesc v) { - /* field -> ['.' | ':'] NAME */ - FuncState fs = this.fs; - expdesc key = new expdesc(); - fs.exp2anyreg(v); - this.next(); /* skip the dot or colon */ - this.checkname(key); - fs.indexed(v, key); - } - - void yindex(expdesc v) { - /* index -> '[' expr ']' */ - this.next(); /* skip the '[' */ - this.expr(v); - this.fs.exp2val(v); - this.checknext(']'); - } - - - /* - ** {====================================================================== - ** Rules for Constructors - ** ======================================================================= - */ - - - static class ConsControl { - expdesc v = new expdesc(); /* last list item read */ - expdesc t; /* table descriptor */ - int nh; /* total number of `record' elements */ - int na; /* total number of array elements */ - int tostore; /* number of array elements pending to be stored */ - }; - - - void recfield(ConsControl cc) { - /* recfield -> (NAME | `['exp1`]') = exp1 */ - FuncState fs = this.fs; - int reg = this.fs.freereg; - expdesc key = new expdesc(); - expdesc val = new expdesc(); - int rkkey; - if (this.t.token == TK_NAME) { - fs.checklimit(cc.nh, MAX_INT, "items in a constructor"); - this.checkname(key); - } else - /* this.t.token == '[' */ - this.yindex(key); - cc.nh++; - this.checknext('='); - rkkey = fs.exp2RK(key); - this.expr(val); - fs.codeABC(Lua.OP_SETTABLE, cc.t.u.s.info, rkkey, fs.exp2RK(val)); - fs.freereg = reg; /* free registers */ - } - - void listfield (ConsControl cc) { - this.expr(cc.v); - fs.checklimit(cc.na, MAX_INT, "items in a constructor"); - cc.na++; - cc.tostore++; - } - - - void constructor(expdesc t) { - /* constructor -> ?? */ - FuncState fs = this.fs; - int line = this.linenumber; - int pc = fs.codeABC(Lua.OP_NEWTABLE, 0, 0, 0); - ConsControl cc = new ConsControl(); - cc.na = cc.nh = cc.tostore = 0; - cc.t = t; - t.init(VRELOCABLE, pc); - cc.v.init(VVOID, 0); /* no value (yet) */ - fs.exp2nextreg(t); /* fix it at stack top (for gc) */ - this.checknext('{'); - do { - LuaC._assert (cc.v.k == VVOID || cc.tostore > 0); - if (this.t.token == '}') - break; - fs.closelistfield(cc); - switch (this.t.token) { - case TK_NAME: { /* may be listfields or recfields */ - this.lookahead(); - if (this.lookahead.token != '=') /* expression? */ - this.listfield(cc); - else - this.recfield(cc); - break; - } - case '[': { /* constructor_item -> recfield */ - this.recfield(cc); - break; - } - default: { /* constructor_part -> listfield */ - this.listfield(cc); - break; - } - } - } while (this.testnext(',') || this.testnext(';')); - this.check_match('}', '{', line); - fs.lastlistfield(cc); - InstructionPtr i = new InstructionPtr(fs.f.code, pc); - LuaC.SETARG_B(i, luaO_int2fb(cc.na)); /* set initial array size */ - LuaC.SETARG_C(i, luaO_int2fb(cc.nh)); /* set initial table size */ - } - - /* - ** converts an integer to a "floating point byte", represented as - ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if - ** eeeee != 0 and (xxx) otherwise. - */ - static int luaO_int2fb (int x) { - int e = 0; /* expoent */ - while (x >= 16) { - x = (x+1) >> 1; - e++; - } - if (x < 8) return x; - else return ((e+1) << 3) | (((int)x) - 8); - } - - - /* }====================================================================== */ - - void parlist () { - /* parlist -> [ param { `,' param } ] */ - FuncState fs = this.fs; - LPrototype f = fs.f; - int nparams = 0; - f.is_vararg = 0; - if (this.t.token != ')') { /* is `parlist' not empty? */ - do { - switch (this.t.token) { - case TK_NAME: { /* param . NAME */ - this.new_localvar(this.str_checkname(), nparams++); - break; - } - case TK_DOTS: { /* param . `...' */ - this.next(); - if (LUA_COMPAT_VARARG) { - /* use `arg' as default name */ - this.new_localvarliteral("arg", nparams++); - f.is_vararg = LuaC.VARARG_HASARG | LuaC.VARARG_NEEDSARG; - } - f.is_vararg |= LuaC.VARARG_ISVARARG; - break; - } - default: this.syntaxerror(" or " + LUA_QL("...") + " expected"); - } - } while ((f.is_vararg==0) && this.testnext(',')); - } - this.adjustlocalvars(nparams); - f.numparams = (fs.nactvar - (f.is_vararg & LuaC.VARARG_HASARG)); - fs.reserveregs(fs.nactvar); /* reserve register for parameters */ - } - - - void body(expdesc e, boolean needself, int line) { - /* body -> `(' parlist `)' chunk END */ - FuncState new_fs = new FuncState(); - open_func(new_fs); - new_fs.f.linedefined = line; - this.checknext('('); - if (needself) { - new_localvarliteral("self", 0); - adjustlocalvars(1); - } - this.parlist(); - this.checknext(')'); - this.chunk(); - new_fs.f.lastlinedefined = this.linenumber; - this.check_match(TK_END, TK_FUNCTION, line); - this.close_func(); - this.pushclosure(new_fs, e); - } - - int explist1(expdesc v) { - /* explist1 -> expr { `,' expr } */ - int n = 1; /* at least one expression */ - this.expr(v); - while (this.testnext(',')) { - fs.exp2nextreg(v); - this.expr(v); - n++; - } - return n; - } - - - void funcargs(expdesc f) { - FuncState fs = this.fs; - expdesc args = new expdesc(); - int base, nparams; - int line = this.linenumber; - switch (this.t.token) { - case '(': { /* funcargs -> `(' [ explist1 ] `)' */ - if (line != this.lastline) - this.syntaxerror("ambiguous syntax (function call x new statement)"); - this.next(); - if (this.t.token == ')') /* arg list is empty? */ - args.k = VVOID; - else { - this.explist1(args); - fs.setmultret(args); - } - this.check_match(')', '(', line); - break; - } - case '{': { /* funcargs -> constructor */ - this.constructor(args); - break; - } - case TK_STRING: { /* funcargs -> STRING */ - this.codestring(args, this.t.seminfo.ts); - this.next(); /* must use `seminfo' before `next' */ - break; - } - default: { - this.syntaxerror("function arguments expected"); - return; - } - } - LuaC._assert (f.k == VNONRELOC); - base = f.u.s.info; /* base register for call */ - if (hasmultret(args.k)) - nparams = Lua.LUA_MULTRET; /* open call */ - else { - if (args.k != VVOID) - fs.exp2nextreg(args); /* close last argument */ - nparams = fs.freereg - (base + 1); - } - f.init(VCALL, fs.codeABC(Lua.OP_CALL, base, nparams + 1, 2)); - fs.fixline(line); - fs.freereg = base+1; /* call remove function and arguments and leaves - * (unless changed) one result */ - } - - - /* - ** {====================================================================== - ** Expression parsing - ** ======================================================================= - */ - - void prefixexp(expdesc v) { - /* prefixexp -> NAME | '(' expr ')' */ - switch (this.t.token) { - case '(': { - int line = this.linenumber; - this.next(); - this.expr(v); - this.check_match(')', '(', line); - fs.dischargevars(v); - return; - } - case TK_NAME: { - this.singlevar(v); - return; - } - default: { - this.syntaxerror("unexpected symbol"); - return; - } - } - } - - - void primaryexp(expdesc v) { - /* - * primaryexp -> prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | - * funcargs } - */ - FuncState fs = this.fs; - this.prefixexp(v); - for (;;) { - switch (this.t.token) { - case '.': { /* field */ - this.field(v); - break; - } - case '[': { /* `[' exp1 `]' */ - expdesc key = new expdesc(); - fs.exp2anyreg(v); - this.yindex(key); - fs.indexed(v, key); - break; - } - case ':': { /* `:' NAME funcargs */ - expdesc key = new expdesc(); - this.next(); - this.checkname(key); - fs.self(v, key); - this.funcargs(v); - break; - } - case '(': - case TK_STRING: - case '{': { /* funcargs */ - fs.exp2nextreg(v); - this.funcargs(v); - break; - } - default: - return; - } - } - } - - - void simpleexp(expdesc v) { - /* - * simpleexp -> NUMBER | STRING | NIL | true | false | ... | constructor | - * FUNCTION body | primaryexp - */ - switch (this.t.token) { - case TK_NUMBER: { - v.init(VKNUM, 0); - v.u.setNval(this.t.seminfo.r); - break; - } - case TK_STRING: { - this.codestring(v, this.t.seminfo.ts); - break; - } - case TK_NIL: { - v.init(VNIL, 0); - break; - } - case TK_TRUE: { - v.init(VTRUE, 0); - break; - } - case TK_FALSE: { - v.init(VFALSE, 0); - break; - } - case TK_DOTS: { /* vararg */ - FuncState fs = this.fs; - this.check_condition(fs.f.is_vararg!=0, "cannot use " + LUA_QL("...") - + " outside a vararg function"); - fs.f.is_vararg &= ~LuaC.VARARG_NEEDSARG; /* don't need 'arg' */ - v.init(VVARARG, fs.codeABC(Lua.OP_VARARG, 0, 1, 0)); - break; - } - case '{': { /* constructor */ - this.constructor(v); - return; - } - case TK_FUNCTION: { - this.next(); - this.body(v, false, this.linenumber); - return; - } - default: { - this.primaryexp(v); - return; - } - } - this.next(); - } - - - int getunopr(int op) { - switch (op) { - case TK_NOT: - return OPR_NOT; - case '-': - return OPR_MINUS; - case '#': - return OPR_LEN; - default: - return OPR_NOUNOPR; - } - } - - - int getbinopr(int op) { - switch (op) { - case '+': - return OPR_ADD; - case '-': - return OPR_SUB; - case '*': - return OPR_MUL; - case '/': - return OPR_DIV; - case '%': - return OPR_MOD; - case '^': - return OPR_POW; - case TK_CONCAT: - return OPR_CONCAT; - case TK_NE: - return OPR_NE; - case TK_EQ: - return OPR_EQ; - case '<': - return OPR_LT; - case TK_LE: - return OPR_LE; - case '>': - return OPR_GT; - case TK_GE: - return OPR_GE; - case TK_AND: - return OPR_AND; - case TK_OR: - return OPR_OR; - default: - return OPR_NOBINOPR; - } - } - - static class Priority { - final byte left; /* left priority for each binary operator */ - - final byte right; /* right priority */ - - public Priority(int i, int j) { - left = (byte) i; - right = (byte) j; - } - }; - - static Priority[] priority = { /* ORDER OPR */ - new Priority(6, 6), new Priority(6, 6), new Priority(7, 7), new Priority(7, 7), new Priority(7, 7), /* `+' `-' `/' `%' */ - new Priority(10, 9), new Priority(5, 4), /* power and concat (right associative) */ - new Priority(3, 3), new Priority(3, 3), /* equality and inequality */ - new Priority(3, 3), new Priority(3, 3), new Priority(3, 3), new Priority(3, 3), /* order */ - new Priority(2, 2), new Priority(1, 1) /* logical (and/or) */ - }; - - static final int UNARY_PRIORITY = 8; /* priority for unary operators */ - - - /* - ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } - ** where `binop' is any binary operator with a priority higher than `limit' - */ - int subexpr(expdesc v, int limit) { - int op; - int uop; - this.enterlevel(); - uop = getunopr(this.t.token); - if (uop != OPR_NOUNOPR) { - this.next(); - this.subexpr(v, UNARY_PRIORITY); - fs.prefix(uop, v); - } else - this.simpleexp(v); - /* expand while operators have priorities higher than `limit' */ - op = getbinopr(this.t.token); - while (op != OPR_NOBINOPR && priority[op].left > limit) { - expdesc v2 = new expdesc(); - int nextop; - this.next(); - fs.infix(op, v); - /* read sub-expression with higher priority */ - nextop = this.subexpr(v2, priority[op].right); - fs.posfix(op, v, v2); - op = nextop; - } - this.leavelevel(); - return op; /* return first untreated operator */ - } - - void expr(expdesc v) { - this.subexpr(v, 0); - } - - /* }==================================================================== */ - - - - /* - ** {====================================================================== - ** Rules for Statements - ** ======================================================================= - */ - - - boolean block_follow (int token) { - switch (token) { - case TK_ELSE: case TK_ELSEIF: case TK_END: - case TK_UNTIL: case TK_EOS: - return true; - default: return false; - } - } - - - void block () { - /* block -> chunk */ - FuncState fs = this.fs; - BlockCnt bl = new BlockCnt(); - fs.enterblock(bl, false); - this.chunk(); - LuaC._assert(bl.breaklist.i == NO_JUMP); - fs.leaveblock(); - } - - - /* - ** structure to chain all variables in the left-hand side of an - ** assignment - */ - static class LHS_assign { - LHS_assign prev; - /* variable (global, local, upvalue, or indexed) */ - expdesc v = new expdesc(); - }; - - - /* - ** check whether, in an assignment to a local variable, the local variable - ** is needed in a previous assignment (to a table). If so, save original - ** local value in a safe place and use this safe copy in the previous - ** assignment. - */ - void check_conflict (LHS_assign lh, expdesc v) { - FuncState fs = this.fs; - int extra = fs.freereg; /* eventual position to save local variable */ - boolean conflict = false; - for (; lh!=null; lh = lh.prev) { - if (lh.v.k == VINDEXED) { - if (lh.v.u.s.info == v.u.s.info) { /* conflict? */ - conflict = true; - lh.v.u.s.info = extra; /* previous assignment will use safe copy */ - } - if (lh.v.u.s.aux == v.u.s.info) { /* conflict? */ - conflict = true; - lh.v.u.s.aux = extra; /* previous assignment will use safe copy */ - } - } - } - if (conflict) { - fs.codeABC(Lua.OP_MOVE, fs.freereg, v.u.s.info, 0); /* make copy */ - fs.reserveregs(1); - } - } - - - void assignment (LHS_assign lh, int nvars) { - expdesc e = new expdesc(); - this.check_condition(VLOCAL <= lh.v.k && lh.v.k <= VINDEXED, - "syntax error"); - if (this.testnext(',')) { /* assignment -> `,' primaryexp assignment */ - LHS_assign nv = new LHS_assign(); - nv.prev = lh; - this.primaryexp(nv.v); - if (nv.v.k == VLOCAL) - this.check_conflict(lh, nv.v); - this.assignment(nv, nvars+1); - } - else { /* assignment . `=' explist1 */ - int nexps; - this.checknext('='); - nexps = this.explist1(e); - if (nexps != nvars) { - this.adjust_assign(nvars, nexps, e); - if (nexps > nvars) - this.fs.freereg -= nexps - nvars; /* remove extra values */ - } - else { - fs.setoneret(e); /* close last expression */ - fs.storevar(lh.v, e); - return; /* avoid default */ - } - } - e.init(VNONRELOC, this.fs.freereg-1); /* default assignment */ - fs.storevar(lh.v, e); - } - - - int cond() { - /* cond -> exp */ - expdesc v = new expdesc(); - /* read condition */ - this.expr(v); - /* `falses' are all equal here */ - if (v.k == VNIL) - v.k = VFALSE; - fs.goiftrue(v); - return v.f.i; - } - - - void breakstat() { - FuncState fs = this.fs; - BlockCnt bl = fs.bl; - boolean upval = false; - while (bl != null && !bl.isbreakable) { - upval |= bl.upval; - bl = bl.previous; - } - if (bl == null) - this.syntaxerror("no loop to break"); - if (upval) - fs.codeABC(Lua.OP_CLOSE, bl.nactvar, 0, 0); - fs.concat(bl.breaklist, fs.jump()); - } - - - void whilestat (int line) { - /* whilestat -> WHILE cond DO block END */ - FuncState fs = this.fs; - int whileinit; - int condexit; - BlockCnt bl = new BlockCnt(); - this.next(); /* skip WHILE */ - whileinit = fs.getlabel(); - condexit = this.cond(); - fs.enterblock(bl, true); - this.checknext(TK_DO); - this.block(); - fs.patchlist(fs.jump(), whileinit); - this.check_match(TK_END, TK_WHILE, line); - fs.leaveblock(); - fs.patchtohere(condexit); /* false conditions finish the loop */ - } - - void repeatstat(int line) { - /* repeatstat -> REPEAT block UNTIL cond */ - int condexit; - FuncState fs = this.fs; - int repeat_init = fs.getlabel(); - BlockCnt bl1 = new BlockCnt(); - BlockCnt bl2 = new BlockCnt(); - fs.enterblock(bl1, true); /* loop block */ - fs.enterblock(bl2, false); /* scope block */ - this.next(); /* skip REPEAT */ - this.chunk(); - this.check_match(TK_UNTIL, TK_REPEAT, line); - condexit = this.cond(); /* read condition (inside scope block) */ - if (!bl2.upval) { /* no upvalues? */ - fs.leaveblock(); /* finish scope */ - fs.patchlist(condexit, repeat_init); /* close the loop */ - } else { /* complete semantics when there are upvalues */ - this.breakstat(); /* if condition then break */ - fs.patchtohere(condexit); /* else... */ - fs.leaveblock(); /* finish scope... */ - fs.patchlist(fs.jump(), repeat_init); /* and repeat */ - } - fs.leaveblock(); /* finish loop */ - } - - - int exp1() { - expdesc e = new expdesc(); - int k; - this.expr(e); - k = e.k; - fs.exp2nextreg(e); - return k; - } - - - void forbody(int base, int line, int nvars, boolean isnum) { - /* forbody -> DO block */ - BlockCnt bl = new BlockCnt(); - FuncState fs = this.fs; - int prep, endfor; - this.adjustlocalvars(3); /* control variables */ - this.checknext(TK_DO); - prep = isnum ? fs.codeAsBx(Lua.OP_FORPREP, base, NO_JUMP) : fs.jump(); - fs.enterblock(bl, false); /* scope for declared variables */ - this.adjustlocalvars(nvars); - fs.reserveregs(nvars); - this.block(); - fs.leaveblock(); /* end of scope for declared variables */ - fs.patchtohere(prep); - endfor = (isnum) ? fs.codeAsBx(Lua.OP_FORLOOP, base, NO_JUMP) : fs - .codeABC(Lua.OP_TFORLOOP, base, 0, nvars); - fs.fixline(line); /* pretend that `Lua.OP_FOR' starts the loop */ - fs.patchlist((isnum ? endfor : fs.jump()), prep + 1); - } - - - void fornum(LString varname, int line) { - /* fornum -> NAME = exp1,exp1[,exp1] forbody */ - FuncState fs = this.fs; - int base = fs.freereg; - this.new_localvarliteral(RESERVED_LOCAL_VAR_FOR_INDEX, 0); - this.new_localvarliteral(RESERVED_LOCAL_VAR_FOR_LIMIT, 1); - this.new_localvarliteral(RESERVED_LOCAL_VAR_FOR_STEP, 2); - this.new_localvar(varname, 3); - this.checknext('='); - this.exp1(); /* initial value */ - this.checknext(','); - this.exp1(); /* limit */ - if (this.testnext(',')) - this.exp1(); /* optional step */ - else { /* default step = 1 */ - fs.codeABx(Lua.OP_LOADK, fs.freereg, fs.numberK(LInteger.valueOf(1))); - fs.reserveregs(1); - } - this.forbody(base, line, 1, true); - } - - - void forlist(LString indexname) { - /* forlist -> NAME {,NAME} IN explist1 forbody */ - FuncState fs = this.fs; - expdesc e = new expdesc(); - int nvars = 0; - int line; - int base = fs.freereg; - /* create control variables */ - this.new_localvarliteral(RESERVED_LOCAL_VAR_FOR_GENERATOR, nvars++); - this.new_localvarliteral(RESERVED_LOCAL_VAR_FOR_STATE, nvars++); - this.new_localvarliteral(RESERVED_LOCAL_VAR_FOR_CONTROL, nvars++); - /* create declared variables */ - this.new_localvar(indexname, nvars++); - while (this.testnext(',')) - this.new_localvar(this.str_checkname(), nvars++); - this.checknext(TK_IN); - line = this.linenumber; - this.adjust_assign(3, this.explist1(e), e); - fs.checkstack(3); /* extra space to call generator */ - this.forbody(base, line, nvars - 3, false); - } - - - void forstat(int line) { - /* forstat -> FOR (fornum | forlist) END */ - FuncState fs = this.fs; - LString varname; - BlockCnt bl = new BlockCnt(); - fs.enterblock(bl, true); /* scope for loop and control variables */ - this.next(); /* skip `for' */ - varname = this.str_checkname(); /* first variable name */ - switch (this.t.token) { - case '=': - this.fornum(varname, line); - break; - case ',': - case TK_IN: - this.forlist(varname); - break; - default: - this.syntaxerror(LUA_QL("=") + " or " + LUA_QL("in") + " expected"); - } - this.check_match(TK_END, TK_FOR, line); - fs.leaveblock(); /* loop scope (`break' jumps to this point) */ - } - - - int test_then_block() { - /* test_then_block -> [IF | ELSEIF] cond THEN block */ - int condexit; - this.next(); /* skip IF or ELSEIF */ - condexit = this.cond(); - this.checknext(TK_THEN); - this.block(); /* `then' part */ - return condexit; - } - - - void ifstat(int line) { - /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] - * END */ - FuncState fs = this.fs; - int flist; - IntPtr escapelist = new IntPtr(NO_JUMP); - flist = test_then_block(); /* IF cond THEN block */ - while (this.t.token == TK_ELSEIF) { - fs.concat(escapelist, fs.jump()); - fs.patchtohere(flist); - flist = test_then_block(); /* ELSEIF cond THEN block */ - } - if (this.t.token == TK_ELSE) { - fs.concat(escapelist, fs.jump()); - fs.patchtohere(flist); - this.next(); /* skip ELSE (after patch, for correct line info) */ - this.block(); /* `else' part */ - } else - fs.concat(escapelist, flist); - fs.patchtohere(escapelist.i); - this.check_match(TK_END, TK_IF, line); - } - - void localfunc() { - expdesc v = new expdesc(); - expdesc b = new expdesc(); - FuncState fs = this.fs; - this.new_localvar(this.str_checkname(), 0); - v.init(VLOCAL, fs.freereg); - fs.reserveregs(1); - this.adjustlocalvars(1); - this.body(b, false, this.linenumber); - fs.storevar(v, b); - /* debug information will only see the variable after this point! */ - fs.getlocvar(fs.nactvar - 1).startpc = fs.pc; - } - - - void localstat() { - /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ - int nvars = 0; - int nexps; - expdesc e = new expdesc(); - do { - this.new_localvar(this.str_checkname(), nvars++); - } while (this.testnext(',')); - if (this.testnext('=')) - nexps = this.explist1(e); - else { - e.k = VVOID; - nexps = 0; - } - this.adjust_assign(nvars, nexps, e); - this.adjustlocalvars(nvars); - } - - - boolean funcname(expdesc v) { - /* funcname -> NAME {field} [`:' NAME] */ - boolean needself = false; - this.singlevar(v); - while (this.t.token == '.') - this.field(v); - if (this.t.token == ':') { - needself = true; - this.field(v); - } - return needself; - } - - - void funcstat(int line) { - /* funcstat -> FUNCTION funcname body */ - boolean needself; - expdesc v = new expdesc(); - expdesc b = new expdesc(); - this.next(); /* skip FUNCTION */ - needself = this.funcname(v); - this.body(b, needself, line); - fs.storevar(v, b); - fs.fixline(line); /* definition `happens' in the first line */ - } - - - void exprstat() { - /* stat -> func | assignment */ - FuncState fs = this.fs; - LHS_assign v = new LHS_assign(); - this.primaryexp(v.v); - if (v.v.k == VCALL) /* stat -> func */ - LuaC.SETARG_C(fs.getcodePtr(v.v), 1); /* call statement uses no results */ - else { /* stat -> assignment */ - v.prev = null; - this.assignment(v, 1); - } - } - - void retstat() { - /* stat -> RETURN explist */ - FuncState fs = this.fs; - expdesc e = new expdesc(); - int first, nret; /* registers with returned values */ - this.next(); /* skip RETURN */ - if (block_follow(this.t.token) || this.t.token == ';') - first = nret = 0; /* return no values */ - else { - nret = this.explist1(e); /* optional return values */ - if (hasmultret(e.k)) { - fs.setmultret(e); - if (e.k == VCALL && nret == 1) { /* tail call? */ - LuaC.SET_OPCODE(fs.getcodePtr(e), Lua.OP_TAILCALL); - LuaC._assert (Lua.GETARG_A(fs.getcode(e)) == fs.nactvar); - } - first = fs.nactvar; - nret = Lua.LUA_MULTRET; /* return all values */ - } else { - if (nret == 1) /* only one single value? */ - first = fs.exp2anyreg(e); - else { - fs.exp2nextreg(e); /* values must go to the `stack' */ - first = fs.nactvar; /* return all `active' values */ - LuaC._assert (nret == fs.freereg - first); - } - } - } - fs.ret(first, nret); - } - - - boolean statement() { - int line = this.linenumber; /* may be needed for error messages */ - switch (this.t.token) { - case TK_IF: { /* stat -> ifstat */ - this.ifstat(line); - return false; - } - case TK_WHILE: { /* stat -> whilestat */ - this.whilestat(line); - return false; - } - case TK_DO: { /* stat -> DO block END */ - this.next(); /* skip DO */ - this.block(); - this.check_match(TK_END, TK_DO, line); - return false; - } - case TK_FOR: { /* stat -> forstat */ - this.forstat(line); - return false; - } - case TK_REPEAT: { /* stat -> repeatstat */ - this.repeatstat(line); - return false; - } - case TK_FUNCTION: { - this.funcstat(line); /* stat -> funcstat */ - return false; - } - case TK_LOCAL: { /* stat -> localstat */ - this.next(); /* skip LOCAL */ - if (this.testnext(TK_FUNCTION)) /* local function? */ - this.localfunc(); - else - this.localstat(); - return false; - } - case TK_RETURN: { /* stat -> retstat */ - this.retstat(); - return true; /* must be last statement */ - } - case TK_BREAK: { /* stat -> breakstat */ - this.next(); /* skip BREAK */ - this.breakstat(); - return true; /* must be last statement */ - } - default: { - this.exprstat(); - return false; /* to avoid warnings */ - } - } - } - - void chunk() { - /* chunk -> { stat [`;'] } */ - boolean islast = false; - this.enterlevel(); - while (!islast && !block_follow(this.t.token)) { - islast = this.statement(); - this.testnext(';'); - LuaC._assert (this.fs.f.maxstacksize >= this.fs.freereg - && this.fs.freereg >= this.fs.nactvar); - this.fs.freereg = this.fs.nactvar; /* free registers */ - } - this.leavelevel(); - } - - /* }====================================================================== */ - -} diff --git a/src/core/org/luaj/compiler/LuaC.java b/src/core/org/luaj/compiler/LuaC.java deleted file mode 100644 index 406d0189..00000000 --- a/src/core/org/luaj/compiler/LuaC.java +++ /dev/null @@ -1,223 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.compiler; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Hashtable; - -import org.luaj.vm.LPrototype; -import org.luaj.vm.LString; -import org.luaj.vm.LValue; -import org.luaj.vm.LoadState; -import org.luaj.vm.LocVars; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaErrorException; -import org.luaj.vm.LoadState.LuaCompiler; - - -/** - * Compiler for Lua - */ -public class LuaC extends Lua implements LuaCompiler { - - /** Install the compiler so that LoadState will first - * try to use it when handed bytes that are - * not already a compiled lua chunk. - */ - public static void install() { - LoadState.compiler = new LuaC(); - } - - protected static void _assert(boolean b) { - if (!b) - throw new LuaErrorException("compiler assert failed"); - } - - public static final int MAXSTACK = 250; - static final int LUAI_MAXUPVALUES = 60; - static final int LUAI_MAXVARS = 200; - static final int NO_REG = MAXARG_A; - - - /* OpMode - basic instruction format */ - static final int - iABC = 0, - iABx = 1, - iAsBx = 2; - - /* OpArgMask */ - static final int - OpArgN = 0, /* argument is not used */ - OpArgU = 1, /* argument is used */ - OpArgR = 2, /* argument is a register or a jump offset */ - OpArgK = 3; /* argument is a constant or register/constant */ - - - static void SET_OPCODE(InstructionPtr i,int o) { - i.set( ( i.get() & (MASK_NOT_OP)) | ((o << POS_OP) & MASK_OP) ); - } - - static void SETARG_A(InstructionPtr i,int u) { - i.set( ( i.get() & (MASK_NOT_A)) | ((u << POS_A) & MASK_A) ); - } - - static void SETARG_B(InstructionPtr i,int u) { - i.set( ( i.get() & (MASK_NOT_B)) | ((u << POS_B) & MASK_B) ); - } - - static void SETARG_C(InstructionPtr i,int u) { - i.set( ( i.get() & (MASK_NOT_C)) | ((u << POS_C) & MASK_C) ); - } - - static void SETARG_Bx(InstructionPtr i,int u) { - i.set( ( i.get() & (MASK_NOT_Bx)) | ((u << POS_Bx) & MASK_Bx) ); - } - - static void SETARG_sBx(InstructionPtr i,int u) { - SETARG_Bx( i, u + MAXARG_sBx ); - } - - static int CREATE_ABC(int o, int a, int b, int c) { - return ((o << POS_OP) & MASK_OP) | - ((a << POS_A) & MASK_A) | - ((b << POS_B) & MASK_B) | - ((c << POS_C) & MASK_C) ; - } - - static int CREATE_ABx(int o, int a, int bc) { - return ((o << POS_OP) & MASK_OP) | - ((a << POS_A) & MASK_A) | - ((bc << POS_Bx) & MASK_Bx) ; - } - - // vector reallocation - - static LValue[] realloc(LValue[] v, int n) { - LValue[] a = new LValue[n]; - if ( v != null ) - System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); - return a; - } - - static LPrototype[] realloc(LPrototype[] v, int n) { - LPrototype[] a = new LPrototype[n]; - if ( v != null ) - System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); - return a; - } - - static LString[] realloc(LString[] v, int n) { - LString[] a = new LString[n]; - if ( v != null ) - System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); - return a; - } - - static LocVars[] realloc(LocVars[] v, int n) { - LocVars[] a = new LocVars[n]; - if ( v != null ) - System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); - return a; - } - - static int[] realloc(int[] v, int n) { - int[] a = new int[n]; - if ( v != null ) - System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); - return a; - } - - static byte[] realloc(byte[] v, int n) { - byte[] a = new byte[n]; - if ( v != null ) - System.arraycopy(v, 0, a, 0, Math.min(v.length,n)); - return a; - } - - public int nCcalls; - Hashtable strings = new Hashtable(); - - /** Utility method to invoke the compiler for an input stream - */ - public static LPrototype compile(InputStream is, String string) throws IOException { - return new LuaC().compile(is.read(), is, string); - } - - /** Compile source bytes into a LPrototype. - * - * Try to compile the file, and return the Prototype on success, - * or throw LuaErrorException on syntax error or I/O Exception - * - * @param firstByte the first byte from the InputStream. - * This can be read by the client and tested to see if it is already a binary chunk. - * @param stream InputStream to read from. - * @param name Name of the chunk - * @return null if the first byte indicates it is a binary chunk, - * a LPrototype instance if it can be compiled, - * or an exception is thrown if there is an error. - * @throws IOException if an I/O exception occurs - * @throws LuaErrorException if there is a syntax error. - */ - public LPrototype compile(int firstByte, InputStream stream, String name) throws IOException { - LuaC compiler = new LuaC(); - return compiler.luaY_parser(firstByte, stream, name); - } - - /** Parse the input */ - private LPrototype luaY_parser(int firstByte, InputStream z, String name) { - LexState lexstate = new LexState(this, z); - FuncState funcstate = new FuncState(); - // lexstate.buff = buff; - lexstate.setinput( this, firstByte, z, new LString(name) ); - lexstate.open_func(funcstate); - /* main func. is always vararg */ - funcstate.f.is_vararg = LuaC.VARARG_ISVARARG; - funcstate.f.source = new LString("@"+name); - lexstate.next(); /* read first token */ - lexstate.chunk(); - lexstate.check(LexState.TK_EOS); - lexstate.close_func(); - LuaC._assert (funcstate.prev == null); - LuaC._assert (funcstate.f.nups == 0); - LuaC._assert (lexstate.fs == null); - return funcstate.f; - } - - public LString newlstr(char[] chars, int offset, int len) { - return newTString( LString.valueOf( new String(chars,offset,len) ) ); - } - - public LString newTString(LString s) { - LString t = (LString) strings.get(s); - if ( t == null ) { - t = LString.newStringCopy(s); - strings.put( t, t ); - } - return t; - } - - public String pushfstring(String string) { - return string; - } - -} diff --git a/src/core/org/luaj/lib/BaseLib.java b/src/core/org/luaj/lib/BaseLib.java deleted file mode 100644 index eefc57b1..00000000 --- a/src/core/org/luaj/lib/BaseLib.java +++ /dev/null @@ -1,504 +0,0 @@ -/** - * - */ -package org.luaj.lib; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; - -import org.luaj.vm.CallInfo; -import org.luaj.vm.LClosure; -import org.luaj.vm.LFunction; -import org.luaj.vm.LNil; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - - - -public class BaseLib extends LFunction { - - public static InputStream STDIN = null; - public static PrintStream STDOUT = System.out; - - private static final String[] NAMES = { - "base", - "print", - "pairs", - "getmetatable", - "setmetatable", - "type", - "pcall", - "ipairs", - "error", - "assert", - "loadfile", - "tonumber", - "rawequal", - "rawget", - "rawset", - "getfenv", - "setfenv", - "select", - "collectgarbage", - "dofile", - "loadstring", - "load", - "tostring", - "unpack", - "xpcall", - "next", - "_inext", // not public - }; - - private static final int INSTALL = 0; - private static final int PRINT = 1; - private static final int PAIRS = 2; - private static final int GETMETATABLE = 3; - private static final int SETMETATABLE = 4; - private static final int TYPE = 5; - private static final int PCALL = 6; - private static final int IPAIRS = 7; - private static final int ERROR = 8; - private static final int ASSERT = 9; - private static final int LOADFILE = 10; - private static final int TONUMBER = 11; - private static final int RAWEQUAL = 12; - private static final int RAWGET = 13; - private static final int RAWSET = 14; - private static final int GETFENV = 15; - private static final int SETFENV = 16; - private static final int SELECT = 17; - private static final int COLLECTGARBAGE = 18; - private static final int DOFILE = 19; - private static final int LOADSTRING = 20; - private static final int LOAD = 21; - private static final int TOSTRING = 22; - private static final int UNPACK = 23; - private static final int XPCALL = 24; - private static final int NEXT = 25; - private static final int INEXT = 26; - - private static LFunction next; - private static LFunction inext; - - public static void install(LTable globals) { - for ( int i=1, n=NAMES.length; i 1 ) - STDOUT.print( "\t" ); - STDOUT.print( vm.tostring(-1) ); - vm.poplvalue(); - } - STDOUT.println(); - return 0; - } - case IPAIRS: { - LTable t = vm.checktable(1); - vm.pushfunction( inext ); - vm.pushlvalue( t ); - vm.pushinteger( 0 ); - return 3; - } - case PAIRS: { - LTable t = vm.checktable(1); - vm.pushfunction( next ); - vm.pushlvalue( t ); - vm.pushnil(); - return 3; - } - case INEXT: { - int i = vm.checkint(2) + 1; - LTable t = vm.checktable(1); - LValue v = t.get(i); - if ( !v.isNil() ) { - vm.pushinteger(i); - vm.pushlvalue(v); - return 2; - } - return 0; - } - case NEXT: { - LTable t = vm.checktable(1); - LValue k = vm.topointer(2); - vm.resettop(); - t.next(vm,k,false); - return -1; - } - case GETMETATABLE: { - vm.checkany(1); - if ( ! vm.getmetatable(1) ) { - vm.pushnil(); - return 1; - } else { - vm.getfield(-1,LValue.TM_METATABLE); - if ( vm.isnil(-1) ) - vm.pop(1); - } - return 1; - } - case SETMETATABLE: { - LTable t = vm.checktable(1); - LValue v = vm.checkany(2); - vm.argcheck(v.isTable() || v.isNil(), 2, "table or nil expected"); - t = t.luaSetMetatable(v); - vm.pushlvalue(t); - return 1; - } - case TYPE: { - LValue v = vm.checkany(1); - vm.pushlstring( v.luaGetTypeName() ); - return 1; - } - case PCALL: { - vm.checkany(1); - int n = vm.gettop(); - int s = vm.pcall( n-1, Lua.LUA_MULTRET ); - if ( s == 0 ) { // success, results are on stack - vm.pushboolean( true ); - vm.insert( 1 ); - return -1; - } else { // error, error message is on the stack - vm.pushboolean( false ); - vm.insert( -2 ); - return 2; - } - } - case XPCALL: { - LValue errfun = vm.checkany(2); - vm.settop(1); - int s = vm.xpcall( 0, Lua.LUA_MULTRET, errfun ); - if ( s == 0 ) { // success, results are on stack - vm.pushboolean( true ); - vm.insert( 1 ); - return -1; - } else { // error, error message is on the stack - vm.pushboolean( false ); - vm.insert( 1 ); - return 2; - } - } - case ERROR: { - vm.error(vm.optstring(1,null), vm.optint(2,-1)); - return 0; - } - case ASSERT: { - if ( ! vm.toboolean(1) ) - vm.error( vm.optstring(2,"assertion failed!") ); - return -1; - } - - case LOADFILE: - loadfile(vm, vm.optstring(1,null)); - return -1; - - case TONUMBER: { - int base = vm.optint(2, 10); - if (base == 10) { /* standard conversion */ - vm.checkany(1); - LValue v = vm.tolnumber(1); - vm.pushlvalue(v); - return 1; - } else { - if ( base < 2 || base > 36 ) - vm.argerror(2, "base out of range"); - LString s = vm.checklstring(1); - vm.pushlvalue( s.luaToNumber(base) ); - return 1; - } - } - case RAWEQUAL: { - LValue a = vm.checkany(1); - LValue b = vm.checkany(2); - vm.pushboolean(a == b); - return 1; - } - case RAWGET: { - LTable t = vm.checktable(1); - LValue k = vm.checkany(2); - vm.pushlvalue( t.get( k ) ); - return 1; - } - case RAWSET: { - LTable t = vm.checktable(1); - LValue k = vm.checkany(2); - LValue v = vm.checkany(3); - t.put( k, v ); - vm.pushlvalue(t); - return 1; - } - case GETFENV: { - LValue f = getfunc(vm, true); - vm.pushlvalue(f.luaGetEnv(vm._G)); - return 1; - } - case SETFENV: { - LTable t = vm.checktable(2); - if ( vm.isnumber(1) && vm.tointeger(1) == 0 ) { - vm._G = t; - } else { - LValue f = getfunc(vm, false); - if ( (!(f instanceof LClosure)) || ! f.luaSetEnv(t) ) - vm.error( "'setfenv' cannot change environment of given object" ); - vm.pushlvalue(f); - return 1; - } - } - case SELECT: { - vm.checkany(1); - int n = vm.gettop(); - if ( vm.isnumber(1) ) { - int index = vm.tolnumber(1).toJavaInt(); - if ( index < 0 ) - index += n; - if ( index <= 0 ) - vm.argerror( 1, "index out of range" ); - if ( index >= n ) - return 0; - else { - return n-index; - } - } else if ( vm.checkstring(1).equals( "#" ) ) { - vm.pushnumber( n - 1 ); - return 1; - } else { - vm.typerror(1,"expected number or '#'"); - return 0; - } - } - case COLLECTGARBAGE: { - String s = vm.optstring(1, "collect"); - int result = 0; - if ( "collect".equals(s) ) - System.gc(); - else if ( "count".equals(s) ) { - Runtime rt = Runtime.getRuntime(); - long used = rt.totalMemory() - rt.freeMemory(); - result = (int) (used >> 10); - } else { - vm.argerror(2,"gc op"); - } - vm.pushnumber(result); - return 1; - } - case DOFILE: - dofile(vm); - return -1; - case LOADSTRING: - loadstring(vm, vm.checklstring(1), vm.optstring(2,"(string)")); - return -1; - case LOAD: - load(vm); - return -1; - case TOSTRING: { - LValue v = vm.checkany(1); - vm.pushlvalue( v.luaAsString() ); - return 1; - } - case UNPACK: { - LTable list = vm.checktable(1); - int n = vm.gettop(); - int i = vm.optint(2,1); - int j; - if ( n >= 3 ) { - j = vm.checkint(3); - } else { - j = list.luaLength(); - } - vm.resettop(); - vm.checkstack(j+1-i); - for ( int k=i; k<=j; k++ ) - vm.pushlvalue(list.get(k)); - return -1; - } - default: - LuaState.vmerror( "bad base id" ); - return 0; - } - } - - private static LValue getfunc (LuaState vm, boolean opt) { - if ( vm.isfunction(1) ) - return vm.tofunction(1); - else { - int level = opt? vm.optint(1, 1): vm.checkint(1); - vm.argcheck(level >= 0, 1, "level must be non-negative"); - vm.argcheck(level-1 <= vm.cc, 1, "invalid level"); - CallInfo ci = vm.getStackFrame(level-1); - if ( ci == null || ci.closure == null ) - return LNil.NIL; - return ci.closure; - } - } - - - public static void redirectOutput( OutputStream newStdOut ) { - STDOUT = new PrintStream( newStdOut ); - } - - public static void restoreStandardOutput() { - STDOUT = System.out; - } - - // closes the input stream, provided its not null or System.in - private static void closeSafely(InputStream is) { - try { - if ( is != null && is != STDIN ) - is.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - // closes the output stream, provided its not null or STDOUT - private static void closeSafely(OutputStream os) { - try { - if ( os != null && os != STDOUT ) - os.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - // return true if loaded, false if error put onto the stack - /** Load a chunk from an input stream, leaving it on the stack if successful, - * then close the input stream if it is not STDIN - * - * @param vm LuaState to load into - * @param is input stream to load from - * @return true if loaded and only item on stack, false if nil+error put onto stack - */ - static boolean loadis(LuaState vm, InputStream is, String chunkname ) { - try { - vm.resettop(); - if ( 0 != vm.load(is, chunkname) ) { - setErrorResult( vm, "cannot load "+chunkname+": "+vm.topointer(-1) ); - return false; - } else { - return true; - } - } finally { - closeSafely( is ); - } - } - - - /** Load a file into a chunk given a filename, leaving it on the stack if successful - * - * @param vm LuaState to load into - * @param fileName file to load, or null to use STDIN - * @return true if loaded and only item on stack, false if nil+error put onto stack - */ - private static boolean loadfile( LuaState vm, String fileName ) { - InputStream is; - - String script; - if ( fileName != null ) { - script = fileName; - is = Platform.getInstance().openFile(fileName); - if ( is == null ) { - setErrorResult( vm, "cannot open "+fileName+": No such file or directory" ); - return false; - } - } else { - is = STDIN != null? STDIN: new ByteArrayInputStream(new byte[0]); - script = "-"; - } - - // use vm to load the script - return loadis( vm, is, script ); - } - - // if load succeeds, return 0 for success, 1 for error (as per lua spec) - private void dofile( LuaState vm ) { - String filename = vm.optstring(1,null); - if ( loadfile( vm, filename ) ) { - vm.call(0, 0); - } else { - vm.error( vm.tostring(-1) ); - } - } - - // return true if loaded, false if error put onto stack - private boolean loadstring(LuaState vm, LString string, String chunkname) { - return loadis( vm, string.toInputStream(), chunkname ); - } - - // return true if loaded, false if error put onto stack - private boolean load(LuaState vm) { - LFunction chunkPartLoader = vm.checkfunction(2); - String chunkname = vm.optstring(3,"=(load)"); - - // load all the parts - LClosure c = (LClosure) chunkPartLoader; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - while ( true ) { - setResult(vm,c); - if ( 0 != vm.pcall(0, 1) ) { - setErrorResult(vm, vm.tostring(2)); - return false; - } - LValue v = vm.topointer(2); - if ( v.isNil() ) - break; - LString s = v.luaAsString(); - s.write(baos, 0, s.length()); - } - - // load the chunk - return loadis( vm, new ByteArrayInputStream( baos.toByteArray() ), chunkname ); - - } catch (IOException ioe) { - setErrorResult(vm, ioe.getMessage()); - return false; - } finally { - closeSafely( baos ); - } - } -} diff --git a/src/core/org/luaj/lib/CoroutineLib.java b/src/core/org/luaj/lib/CoroutineLib.java deleted file mode 100644 index 6f465810..00000000 --- a/src/core/org/luaj/lib/CoroutineLib.java +++ /dev/null @@ -1,141 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import org.luaj.vm.LFunction; -import org.luaj.vm.LTable; -import org.luaj.vm.LThread; -import org.luaj.vm.LuaState; - -public class CoroutineLib extends LFunction { - - private static final String[] NAMES = { - "install", - "create", - "resume", - "running", - "status", - "wrap", - "yield", - "wrapped" - }; - - private static final int INSTALL = 0; - private static final int CREATE = 1; - private static final int RESUME = 2; - private static final int RUNNING = 3; - private static final int STATUS = 4; - private static final int WRAP = 5; - private static final int YIELD = 6; - private static final int WRAPPED = 7; - - public static void install( LTable globals ) { - LTable lib = new LTable(0,6); - for ( int i=1; i<=YIELD; i++ ) - lib.put(NAMES[i], new CoroutineLib(i)); - globals.put("coroutine",lib); - PackageLib.setIsLoaded("coroutine", lib); - } - - private final int id; - private final LThread thread; - - public CoroutineLib() { - this.id = 0; - this.thread = null; - } - - private CoroutineLib( int id ) { - this.id = id; - this.thread = null; - } - - public String toString() { - return NAMES[id]+"()"; - } - - private CoroutineLib( int id, LThread thread ) { - this.id = id; - this.thread = thread; - } - - public int invoke( LuaState vm ) { - switch ( id ) { - case INSTALL: { - install(vm._G); - return 0; - } - case CREATE: { - LFunction c = vm.checkfunction(1); - vm.pushlvalue( new LThread( c, c.luaGetEnv(vm._G) ) ); - return 1; - } - case RESUME: { - LThread t = vm.checkthread(1); - t.resumeFrom( vm, vm.gettop()-1 ); - return -1; - } - case RUNNING: { - LThread r = LThread.getRunning(); - if ( r != null ) { - vm.pushlvalue( r ); - } else { - vm.pushnil(); - } - return 1; - } - case STATUS: { - vm.pushstring( vm.checkthread(1).getStatus() ); - return 1; - } - case WRAP: { - LFunction c = vm.checkfunction(1); - vm.pushlvalue( new CoroutineLib(WRAPPED,new LThread(c, c.luaGetEnv(vm._G))) ); - return 1; - } - case YIELD: { - LThread r = LThread.getRunning(); - if ( r == null ) { - vm.error("main thread can't yield"); - return 0; - } - r.yield(); - return -1; - } - case WRAPPED: { - LThread t = this.thread; - t.resumeFrom( vm, vm.gettop() ); - if ( vm.toboolean(1) ) { - vm.remove(1); - return -1; - } else { - vm.error( vm.tostring(2) ); - return 0; - } - } - default: { - LuaState.vmerror( "bad coroutine id" ); - return 0; - } - } - } -} diff --git a/src/core/org/luaj/lib/DebugLib.java b/src/core/org/luaj/lib/DebugLib.java deleted file mode 100644 index 2c6e8d96..00000000 --- a/src/core/org/luaj/lib/DebugLib.java +++ /dev/null @@ -1,824 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - - -import org.luaj.vm.CallInfo; -import org.luaj.vm.LBoolean; -import org.luaj.vm.LClosure; -import org.luaj.vm.LFunction; -import org.luaj.vm.LInteger; -import org.luaj.vm.LNil; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaErrorException; -import org.luaj.vm.LuaState; -import org.luaj.vm.UpVal; - -public class DebugLib extends LFunction { - - private static final String[] NAMES = { - "debuglib", - "debug", - "getfenv", - "gethook", - "getinfo", - "getlocal", - "getmetatable", - "getregistry", - "getupvalue", - "setfenv", - "sethook", - "setlocal", - "setmetatable", - "setupvalue", - "traceback", - }; - - private static final int INSTALL = 0; - private static final int DEBUG = 1; - private static final int GETFENV = 2; - private static final int GETHOOK = 3; - private static final int GETINFO = 4; - private static final int GETLOCAL = 5; - private static final int GETMETATABLE = 6; - private static final int GETREGISTRY = 7; - private static final int GETUPVALUE = 8; - private static final int SETFENV = 9; - private static final int SETHOOK = 10; - private static final int SETLOCAL = 11; - private static final int SETMETATABLE = 12; - private static final int SETUPVALUE = 13; - private static final int TRACEBACK = 14; - - /* maximum stack for a Lua function */ - private static final int MAXSTACK = 250; - - private static final LString LUA = new LString("Lua"); - private static final LString JAVA = new LString("Java"); - private static final LString JAVASRC = new LString("[Java]"); - private static final LString QMARK = new LString("?"); - private static final LString GLOBAL = new LString("global"); - private static final LString LOCAL = new LString("local"); - private static final LString METHOD = new LString("method"); - private static final LString UPVALUE = new LString("upvalue"); - private static final LString FIELD = new LString("field"); - private static final LString NOSTRING = new LString(""); - - public static void install( LuaState vm ) { - LTable debug = new LTable(); - for (int i = 1; i < NAMES.length; i++) - debug.put(NAMES[i], new DebugLib(i)); - vm._G.put("debug", debug); - PackageLib.setIsLoaded("debug", debug); - } - - private final int id; - - public DebugLib() { - this.id = INSTALL; - } - - private DebugLib( int id ) { - this.id = id; - } - - public String toString() { - return NAMES[id]+"()"; - } - - public int invoke( LuaState vm ) { - switch ( id ) { - case INSTALL: - install(vm); - return 0; - case DEBUG: - return debug(vm); - case GETFENV: - return getfenv(vm); - case GETHOOK: - return gethook(vm); - case GETINFO: - return getinfo(vm); - case GETLOCAL: - return getlocal(vm); - case GETMETATABLE: - return getmetatable(vm); - case GETREGISTRY: - return getregistry(vm); - case GETUPVALUE: - return getupvalue(vm); - case SETFENV: - return setfenv(vm); - case SETHOOK: - return sethook(vm); - case SETLOCAL: - return setlocal(vm); - case SETMETATABLE: - return setmetatable(vm); - case SETUPVALUE: - return setupvalue(vm); - case TRACEBACK: - return traceback(vm); - default: - LuaState.vmerror( "bad package id" ); - return 0; - } - } - - // j2se subclass may wish to override and provide actual console here. - // j2me platform has not System.in to provide console. - protected int debug(LuaState vm) { - return 0; - } - - protected int gethook(LuaState vm) { - LuaState threadVm = optthreadvm(vm, 1); - LValue hook = threadVm.gethook(); - int mask = threadVm.gethookmask(); - int count = threadVm.gethookcount(); - vm.pushlvalue(hook!=null? hook: LNil.NIL); - vm.pushstring("" - +((mask&LuaState.LUA_MASKCALL)!=0? "c": "") - +((mask&LuaState.LUA_MASKRET) !=0? "r": "") - +((mask&LuaState.LUA_MASKLINE)!=0? "l": "")); - vm.pushinteger(count); - return 3; - } - - protected LuaState optthreadvm(LuaState vm, int index) { - if ( ! vm.isthread(index) ) - return vm; - LuaState threadVm = vm.checkthread(index).vm; - vm.remove(index); - return threadVm; - } - - protected int sethook(LuaState vm) { - LuaState threadVm = optthreadvm(vm, 1); - LFunction func = vm.isnoneornil(1)? null: vm.checkfunction(1); - String str = vm.optstring(2,""); - int count = vm.optint(3,0); - int mask = 0; - for ( int i=0; i= 0 ) - lines.put(1, LInteger.valueOf(line)); - } - break; - } - } - } - return 1; - } - - protected int getlocal(LuaState vm) { - LuaState threadVm = optthreadvm(vm, 1); - int level = vm.checkint(1); - int local = vm.checkint(2); - StackInfo si = getstackinfo(threadVm, level, 1)[0]; - CallInfo ci = (si!=null? si.luainfo: null); - LPrototype p = (ci!=null? ci.closure.p: null); - LString name = (p!=null? p.getlocalname(local, ci.currentpc()): null); - if ( name != null ) { - LValue value = threadVm.stack[ci.base+(local-1)]; - vm.pushlvalue( name ); - vm.pushlvalue( value ); - return 2; - } else { - vm.pushnil(); - return 1; - } - } - - protected int setlocal(LuaState vm) { - LuaState threadVm = optthreadvm(vm, 1); - int level = vm.checkint(1); - int local = vm.checkint(2); - LValue value = vm.topointer(3); - StackInfo si = getstackinfo(threadVm, level, 1)[0]; - CallInfo ci = (si!=null? si.luainfo: null); - LPrototype p = (ci!=null? ci.closure.p: null); - LString name = (p!=null? p.getlocalname(local, ci.currentpc()): null); - if ( name != null ) { - threadVm.stack[ci.base+(local-1)] = value; - vm.pushlvalue( name ); - } else { - vm.pushnil(); - } - return 1; - } - - protected int getmetatable(LuaState vm) { - LValue object = vm.topointer(1); - LValue mt = object.luaGetMetatable(); - if ( mt != null ) - vm.pushlvalue( object.luaGetMetatable() ); - else - vm.pushnil(); - return 1; - } - - protected int setmetatable(LuaState vm) { - LValue object = vm.topointer(1); - try { - if ( ! vm.isnoneornil(2) ) - object.luaSetMetatable(vm.checktable(3)); - else - object.luaSetMetatable(null); - vm.pushboolean(true); - return 1; - } catch ( LuaErrorException e ) { - vm.pushboolean(false); - vm.pushstring(e.toString()); - return 2; - } - } - - protected int getregistry(LuaState vm) { - vm.pushlvalue( new LTable() ); - return 1; - } - - private static LString findupvalue(LClosure c, int up) { - if ( c.upVals != null && up > 0 && up <= c.upVals.length ) { - if ( c.p.upvalues != null && up <= c.p.upvalues.length ) - return c.p.upvalues[up-1]; - else - return new LString( "."+up+"" ); - } - return null; - } - - protected int getupvalue(LuaState vm) { - LFunction func = vm.checkfunction(1); - int up = vm.checkint(2); - vm.resettop(); - if ( func.isClosure() ) { - LClosure c = (LClosure) func; - LString name = findupvalue(c, up); - if ( name != null ) { - vm.pushlstring(name); - vm.pushlvalue(c.upVals[up-1].getValue()); - return 2; - } - } - vm.pushnil(); - return 1; - } - - protected int setupvalue(LuaState vm) { - LFunction func = vm.checkfunction(1); - int up = vm.checkint(2); - LValue value = vm.topointer(3); - vm.resettop(); - if ( func instanceof LClosure ) { - LClosure c = (LClosure) func; - LString name = findupvalue(c, up); - if ( name != null ) { - c.upVals[up-1].setValue(value); - vm.pushlstring(name); - return 1; - } - } - vm.pushnil(); - return 1; - } - - protected int traceback(LuaState vm) { - LuaState threadVm = optthreadvm(vm, 1); - String message = "stack traceback:\n"; - int level = vm.optint(2,1); - if ( ! vm.isnoneornil(1) ) - message = vm.checkstring(1)+"\n"; - String tb = DebugLib.traceback(threadVm, level); - vm.pushstring(message+tb); - return 1; - } - - // =================== public utilities ==================== - - /** - * @param callinfo the CallInfo to inspect - * @param up the 1-based index of the local - * @return { name, value } or null if not found. - */ - public static LValue[] getlocal(LuaState vm, CallInfo ci, int local) { - LPrototype p = (ci!=null? ci.closure.p: null); - LString name = (p!=null? p.getlocalname(local, ci.currentpc()): null); - if ( name != null ) { - LValue value = vm.stack[ci.base+(local-1)]; - return new LValue[] { name, value }; - } else { - return null; - } - } - - /** - * @param c the LClosure to inspect - * @param up the 1-based index of the upvalue - * @return { name, value, isclosed } or null if not found. - */ - public static LValue[] getupvalue(LClosure c, int up) { - LString name = findupvalue(c, up); - if ( name != null ) { - UpVal u = c.upVals[up-1]; - LValue value = u.getValue(); - boolean isclosed = u.isClosed(); - return new LValue[] { name, value, LBoolean.valueOf(isclosed) }; - } - return null; - } - - /** - * Get a traceback as a string for an arbitrary LuaState - */ - public static String traceback(LuaState vm, int level) { - StackInfo[] s = getstackinfo(vm, level, 10); - StringBuffer sb = new StringBuffer(); - for ( int i=0; i=0? getobjname(vm, caller, stackpos): null); - } - public int currentline() { - return luainfo!=null? luainfo.currentline(): -1; - } - public String tracename() { - if ( caller == null ) - return "main chunk"; - if ( func != null ) - return func.toString(); - LString[] kind = getfunckind(); - if ( kind == null ) - return "function ?"; - return "function "+kind[0].toJavaString(); - } - } - - - /** - * @param level first level to report - * @return array StackInfo with countlevels items, some may be null! - */ - private static StackInfo[] getstackinfo(LuaState vm, int level, int countlevels) { - StackInfo[] si = new StackInfo[countlevels]; - int i = 0; - LClosure prevclosure = null; - for (int j=vm.cc; j>=0; --j) { - - CallInfo ci = vm.calls[j]; - LFunction f = ci.currentfunc(vm); - - // java, or tailcall? - if ( f != null && (! f.isClosure() || f!=prevclosure) ) { - if ( (level--) <= 0 ) { - si[i++] = new StackInfo( vm, ci, ci.currentfunca(vm), null, f); - if ( i >= countlevels ) - return si; - } - } - - // add the lua closure - if ( (level--) <= 0 ) { - if (j>0 && vm.calls[j-1].currentfunc(vm) == ci.closure) { - CallInfo caller = vm.calls[j-1]; - int callera = caller.currentfunca(vm); - si[i++] = new StackInfo( vm, caller, callera, ci, ci.closure); - } else { - si[i++] = new StackInfo( vm, null, -1, ci, ci.closure); - } - if ( i >= countlevels ) - return si; - } - prevclosure = ci.closure; - } - - return si; - } - - // look up a function in the stack, if it exists - private static StackInfo findstackinfo(LuaState vm, LFunction func) { - for (int j=vm.cc; j>=0; --j) { - CallInfo ci = vm.calls[j]; - int instr = ci.closure.p.code[ci.currentpc()]; - if ( Lua.GET_OPCODE(instr) == Lua.OP_CALL ) { - int a = Lua.GETARG_A(instr); - if ( func == vm.stack[ci.base + a] ) - return new StackInfo(vm, ci, a, null, func); - if ( func == ci.closure ) - return new StackInfo(vm, (j>0? vm.calls[j-1]: null), 0, ci, null); - } - } - return new StackInfo(vm, null, -1, null, func); - } - - // return LString[] { name, namewhat } if found, null if not - private static LString[] getobjname(LuaState L, CallInfo ci, int stackpos) { - LString name; - if (ci.isLua()) { /* a Lua function? */ - LPrototype p = ci.closure.p; - int pc = (ci.pc > 0 ? ci.pc - 1 : 0); // currentpc(L, ci); - int i;// Instruction i; - name = p.getlocalname(stackpos + 1, pc); - if (name != null) /* is a local? */ - return new LString[] { name, LOCAL }; - i = symbexec(p, pc, stackpos); /* try symbolic execution */ - lua_assert(pc != -1); - switch (Lua.GET_OPCODE(i)) { - case Lua.OP_GETGLOBAL: { - int g = Lua.GETARG_Bx(i); /* global index */ - // lua_assert(p.k[g].isString()); - return new LString[] { p.k[g].luaAsString(), GLOBAL }; - } - case Lua.OP_MOVE: { - int a = Lua.GETARG_A(i); - int b = Lua.GETARG_B(i); /* move from `b' to `a' */ - if (b < a) - return getobjname(L, ci, b); /* get name for `b' */ - break; - } - case Lua.OP_GETTABLE: { - int k = Lua.GETARG_C(i); /* key index */ - name = kname(p, k); - return new LString[] { name, FIELD }; - } - case Lua.OP_GETUPVAL: { - int u = Lua.GETARG_B(i); /* upvalue index */ - name = u < p.upvalues.length ? p.upvalues[u] : QMARK; - return new LString[] { name, UPVALUE }; - } - case Lua.OP_SELF: { - int k = Lua.GETARG_C(i); /* key index */ - name = kname(p, k); - return new LString[] { name, METHOD }; - } - default: - break; - } - } - return null; /* no useful name found */ - } - - private static LString kname(LPrototype p, int c) { - if (Lua.ISK(c) && p.k[Lua.INDEXK(c)].isString()) - return p.k[Lua.INDEXK(c)].luaAsString(); - else - return QMARK; - } - - private static boolean checkreg(LPrototype pt,int reg) { - return (reg < pt.maxstacksize); - } - - private static boolean precheck(LPrototype pt) { - if (!(pt.maxstacksize <= MAXSTACK)) return false; - lua_assert(pt.numparams + (pt.is_vararg & Lua.VARARG_HASARG) <= pt.maxstacksize); - lua_assert((pt.is_vararg & Lua.VARARG_NEEDSARG) == 0 - || (pt.is_vararg & Lua.VARARG_HASARG) != 0); - if (!(pt.upvalues.length <= pt.nups)) return false; - if (!(pt.lineinfo.length == pt.code.length || pt.lineinfo.length == 0)) return false; - if (!(Lua.GET_OPCODE(pt.code[pt.code.length - 1]) == Lua.OP_RETURN)) return false; - return true; - } - - private static boolean checkopenop(LPrototype pt,int pc) { - int i = pt.code[(pc)+1]; - switch (Lua.GET_OPCODE(i)) { - case Lua.OP_CALL: - case Lua.OP_TAILCALL: - case Lua.OP_RETURN: - case Lua.OP_SETLIST: { - if (!(Lua.GETARG_B(i) == 0)) return false; - return true; - } - default: - return false; /* invalid instruction after an open call */ - } - } - - //static int checkArgMode (LPrototype pt, int r, enum OpArgMask mode) { - private static boolean checkArgMode (LPrototype pt, int r, int mode) { - switch (mode) { - case Lua.OpArgN: if (!(r == 0)) return false; break; - case Lua.OpArgU: break; - case Lua.OpArgR: checkreg(pt, r); break; - case Lua.OpArgK: - if (!(Lua.ISK(r) ? Lua.INDEXK(r) < pt.k.length : r < pt.maxstacksize)) return false; - break; - } - return true; - } - - - // return last instruction, or 0 if error - private static int symbexec(LPrototype pt, int lastpc, int reg) { - int pc; - int last; /* stores position of last instruction that changed `reg' */ - last = pt.code.length - 1; /* - * points to final return (a `neutral' - * instruction) - */ - if (!(precheck(pt))) return 0; - for (pc = 0; pc < lastpc; pc++) { - int i = pt.code[pc]; - int op = Lua.GET_OPCODE(i); - int a = Lua.GETARG_A(i); - int b = 0; - int c = 0; - if (!(op < Lua.NUM_OPCODES)) return 0; - if (!checkreg(pt, a)) return 0; - switch (Lua.getOpMode(op)) { - case Lua.iABC: { - b = Lua.GETARG_B(i); - c = Lua.GETARG_C(i); - if (!(checkArgMode(pt, b, Lua.getBMode(op)))) return 0; - if (!(checkArgMode(pt, c, Lua.getCMode(op)))) return 0; - break; - } - case Lua.iABx: { - b = Lua.GETARG_Bx(i); - if (Lua.getBMode(op) == Lua.OpArgK) - if (!(b < pt.k.length)) return 0; - break; - } - case Lua.iAsBx: { - b = Lua.GETARG_sBx(i); - if (Lua.getBMode(op) == Lua.OpArgR) { - int dest = pc + 1 + b; - if (!(0 <= dest && dest < pt.code.length)) return 0; - if (dest > 0) { - /* cannot jump to a setlist count */ - int d = pt.code[dest - 1]; - if ((Lua.GET_OPCODE(d) == Lua.OP_SETLIST && Lua.GETARG_C(d) == 0)) return 0; - } - } - break; - } - } - if (Lua.testAMode(op)) { - if (a == reg) - last = pc; /* change register `a' */ - } - if (Lua.testTMode(op)) { - if (!(pc + 2 < pt.code.length)) return 0; /* check skip */ - if (!(Lua.GET_OPCODE(pt.code[pc + 1]) == Lua.OP_JMP)) return 0; - } - switch (op) { - case Lua.OP_LOADBOOL: { - if (!(c == 0 || pc + 2 < pt.code.length)) return 0; /* check its jump */ - break; - } - case Lua.OP_LOADNIL: { - if (a <= reg && reg <= b) - last = pc; /* set registers from `a' to `b' */ - break; - } - case Lua.OP_GETUPVAL: - case Lua.OP_SETUPVAL: { - if (!(b < pt.nups)) return 0; - break; - } - case Lua.OP_GETGLOBAL: - case Lua.OP_SETGLOBAL: { - if (!(pt.k[b].isString())) return 0; - break; - } - case Lua.OP_SELF: { - if (!checkreg(pt, a + 1)) return 0; - if (reg == a + 1) - last = pc; - break; - } - case Lua.OP_CONCAT: { - if (!(b < c)) return 0; /* at least two operands */ - break; - } - case Lua.OP_TFORLOOP: { - if (!(c >= 1)) return 0; /* at least one result (control variable) */ - if (!checkreg(pt, a + 2 + c)) return 0; /* space for results */ - if (reg >= a + 2) - last = pc; /* affect all regs above its base */ - break; - } - case Lua.OP_FORLOOP: - case Lua.OP_FORPREP: - if (!checkreg(pt, a + 3)) return 0; - /* go through */ - case Lua.OP_JMP: { - int dest = pc + 1 + b; - /* not full check and jump is forward and do not skip `lastpc'? */ - if (reg != Lua.NO_REG && pc < dest && dest <= lastpc) - pc += b; /* do the jump */ - break; - } - case Lua.OP_CALL: - case Lua.OP_TAILCALL: { - if (b != 0) { - if (!checkreg(pt, a + b - 1)) return 0; - } - c--; /* c = num. returns */ - if (c == Lua.LUA_MULTRET) { - if (!(checkopenop(pt, pc))) return 0; - } else if (c != 0) - if (!checkreg(pt, a + c - 1)) return 0; - if (reg >= a) - last = pc; /* affect all registers above base */ - break; - } - case Lua.OP_RETURN: { - b--; /* b = num. returns */ - if (b > 0) - if (!checkreg(pt, a + b - 1)) return 0; - break; - } - case Lua.OP_SETLIST: { - if (b > 0) - if (!checkreg(pt, a + b)) return 0; - if (c == 0) - pc++; - break; - } - case Lua.OP_CLOSURE: { - int nup, j; - if (!(b < pt.p.length)) return 0; - nup = pt.p[b].nups; - if (!(pc + nup < pt.code.length)) return 0; - for (j = 1; j <= nup; j++) { - int op1 = Lua.GET_OPCODE(pt.code[pc + j]); - if (!(op1 == Lua.OP_GETUPVAL || op1 == Lua.OP_MOVE)) return 0; - } - if (reg != Lua.NO_REG) /* tracing? */ - pc += nup; /* do not 'execute' these pseudo-instructions */ - break; - } - case Lua.OP_VARARG: { - if (!((pt.is_vararg & Lua.VARARG_ISVARARG) != 0 - && (pt.is_vararg & Lua.VARARG_NEEDSARG) == 0)) return 0; - b--; - if (b == Lua.LUA_MULTRET) - if (!(checkopenop(pt, pc))) return 0; - if (!checkreg(pt, a + b - 1)) return 0; - break; - } - default: - break; - } - } - return pt.code[last]; - } - -} diff --git a/src/core/org/luaj/lib/IoLib.java b/src/core/org/luaj/lib/IoLib.java deleted file mode 100644 index 7804d713..00000000 --- a/src/core/org/luaj/lib/IoLib.java +++ /dev/null @@ -1,513 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import java.io.ByteArrayOutputStream; -import java.io.EOFException; -import java.io.IOException; - -import org.luaj.vm.LFunction; -import org.luaj.vm.LNil; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LUserData; -import org.luaj.vm.LValue; -import org.luaj.vm.LuaState; - - -abstract -public class IoLib extends LFunction { - - protected interface File { - public void write( LString string ) throws IOException; - public void flush() throws IOException; - public boolean isstdfile(); - public void close() throws IOException; - public boolean isclosed(); - // returns new position - public int seek(String option, int bytecount) throws IOException; - public void setvbuf(String mode, int size); - // get length remaining to read - public int remaining() throws IOException; - // peek ahead one character - public int peek() throws IOException, EOFException; - // return char if read, -1 if eof, throw IOException on other exception - public int read() throws IOException, EOFException; - // return number of bytes read if positive, false if eof, throw IOException on other exception - public int read(byte[] bytes, int offset, int length) throws IOException; - } - - - /** - * Create a function stub with a specific index (factory method) - */ - abstract protected IoLib newInstance( int index ); - - /** - * Wrap the standard input. - * @return File - * @throws IOException - */ - abstract protected File wrapStdin() throws IOException; - - /** - * Wrap the standard output. - * @return File - * @throws IOException - */ - abstract protected File wrapStdout() throws IOException; - - /** - * Open a file in a particular mode. - * @param filename - * @param mode - * @return File object if successful - * @throws IOException if could not be opened - */ - abstract protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException; - - /** - * Open a temporary file. - * @return File object if successful - * @throws IOException if could not be opened - */ - abstract protected File tmpFile() throws IOException; - - /** - * Start a new process and return a file for input or output - * @param prog the program to execute - * @param mode "r" to read, "w" to write - * @return File to read to or write from - * @throws IOException if an i/o exception occurs - */ - abstract protected File openProgram(String prog, String mode) throws IOException; - - - public static final String[] NAMES = { - "io", - "__index", - "close", - "flush", - "input", - "lines", - "open", - "output", - "popen", - "read", - "tmpfile", - "type", - "write", - "close", - "flush", - "lines", - "read", - "seek", - "setvbuf", - "write", - }; - - private static final int INSTALL = 0; - private static final int IO_INDEX = 1; - private static final int IO_CLOSE = 2; - private static final int IO_FLUSH = 3; - private static final int IO_INPUT = 4; - private static final int IO_LINES = 5; - private static final int IO_OPEN = 6; - private static final int IO_OUTPUT = 7; - private static final int IO_POPEN = 8; - private static final int IO_READ = 9; - private static final int IO_TMPFILE = 10; - private static final int IO_TYPE = 11; - private static final int IO_WRITE = 12; - private static final int FILE_CLOSE = 13; - private static final int FILE_FLUSH = 14; - private static final int FILE_LINES = 15; - private static final int FILE_READ = 16; - private static final int FILE_SEEK = 17; - private static final int FILE_SETVBUF = 18; - private static final int FILE_WRITE = 19; - - private static File INPUT = null; - private static File OUTPUT = null; - private static File ERROR = null; - - private static LTable FILE_MT; - - protected void initialize( LTable globals ) { - LTable io = new LTable(); - for ( int i=IO_INDEX; i<=IO_WRITE; i++ ) - io.put(NAMES[i], newInstance(i)); - io.luaSetMetatable(io); - FILE_MT = new LTable(); - for ( int i=FILE_CLOSE; i<=FILE_WRITE; i++ ) - FILE_MT.put(NAMES[i], newInstance(i)); - FILE_MT.put("__index", FILE_MT); - INPUT = null; - OUTPUT = null; - ERROR = null; - globals.put( "io", io ); - PackageLib.setIsLoaded("io", io); - } - - private final int id; - - protected IoLib() { - id = 0; - } - - protected IoLib( int id ) { - this.id = id; - } - - public LString luaAsString() { - return new LString(toJavaString()); - } - - public String toJavaString() { - return "io."+toString(); - } - - public String toString() { - return NAMES[id]+"()"; - } - - private File input(LuaState vm) { - return INPUT!=null? INPUT: (INPUT=ioopenfile(vm,"-","r")); - } - - private File output(LuaState vm) { - return OUTPUT!=null? OUTPUT: (OUTPUT=ioopenfile(vm,"-","w")); - } - - private File error(LuaState vm) { - return ERROR!=null? ERROR: (ERROR=ioopenfile(vm,"-","w")); - } - - public LValue __index(LuaState vm, LValue table, LValue key) { - String k = key.toJavaString(); - if ( "stdout".equals(k) ) - return touserdata(output(vm)); - else if ( "stdin".equals(k) ) - return touserdata(input(vm)); - else if ( "stderr".equals(k) ) - return touserdata(error(vm)); - else - return LNil.NIL; - } - - public int invoke( LuaState vm ) { - File f; - int n; - try { - switch ( id ) { - /* Load the table library dynamically */ - case INSTALL: - initialize(vm._G); - return 0; - case IO_CLOSE: - f = vm.isnoneornil(1)? - output(vm): - checkfile(vm,1); - checkopen(vm, f); - ioclose(vm,f); - break; - case IO_FLUSH: - checkopen(vm,output(vm)); - OUTPUT.flush(); - vm.pushboolean(true); - return 1; - case IO_INPUT: - INPUT = vm.isnoneornil(1)? - input(vm): - vm.isstring(1)? - ioopenfile(vm,vm.checkstring(1),"r"): - checkfile(vm,1); - setresult(vm, INPUT); - break; - case IO_LINES: - INPUT = vm.isnoneornil(1)? - input(vm): - ioopenfile(vm,vm.checkstring(1),"r"); - checkopen(vm, INPUT); - vm.pushlvalue(lines(vm,INPUT)); - return 1; - case IO_OPEN: - setresult(vm, rawopenfile(vm.checkstring(1), vm.optstring(2,"r"))); - break; - case IO_OUTPUT: - OUTPUT = vm.isnoneornil(1)? - output(vm): - vm.isstring(1)? - ioopenfile(vm,vm.checkstring(1),"w"): - checkfile(vm,1); - setresult(vm, OUTPUT); - break; - case IO_POPEN: - setresult(vm, openProgram(vm.checkstring(1),vm.optstring(2, "r"))); - break; - case IO_READ: - checkopen(vm, INPUT); - ioread( vm, INPUT ); - break; - case IO_TMPFILE: - setresult(vm, tmpFile()); - break; - case IO_TYPE: - f = optfile(vm,1); - if ( f != null ) - vm.pushstring(f.isclosed()? "closed file": "file"); - else - vm.pushnil(); - return 1; - case IO_WRITE: - checkopen(vm, output(vm)); - iowrite( vm, OUTPUT ); - break; - case FILE_CLOSE: - f = checkfile(vm,1); - ioclose(vm, f); - break; - case FILE_FLUSH: - f = checkfile(vm,1); - f.flush(); - vm.pushboolean(true); - return 1; - case FILE_LINES: - f = checkfile(vm,1); - vm.pushlvalue(lines(vm,f)); - return 1; - case FILE_READ: - f = checkfile(vm,1); - vm.remove(1); - ioread(vm, f); - break; - case FILE_SEEK: - f = checkfile(vm,1); - vm.remove(1); - n = f.seek(vm.optstring(1,"cur"),vm.optint(2, 0)); - vm.pushinteger(n); - return 1; - case FILE_SETVBUF: - f = checkfile(vm,1); - vm.remove(1); - f.setvbuf(vm.checkstring(1),vm.optint(2, 1024)); - vm.pushboolean(true); - return 1; - case FILE_WRITE: - f = checkfile(vm,1); - vm.remove(1); - iowrite( vm, f ); - break; - default: - LuaState.vmerror( "bad io id" ); - } - } catch ( IOException ioe ) { - seterrorresult(vm,ioe); - } - return -1; - } - - private static void ioclose(LuaState vm, File f) throws IOException { - if ( f.isstdfile() ) - seterrorresult(vm,"cannot close standard file"); - else { - f.close(); - setsuccessresult(vm); - } - } - - private static void setsuccessresult(LuaState vm) { - vm.resettop(); - vm.pushboolean(true); - } - - private static void seterrorresult(LuaState vm, IOException ioe) { - String s = ioe.getMessage(); - seterrorresult(vm, "io error: "+(s!=null? s: ioe.toString())); - } - - private static void seterrorresult(LuaState vm, String errortext) { - vm.resettop(); - vm.pushnil(); - vm.pushstring(errortext); - } - - private LValue lines(LuaState vm, final File f) { - return new LFunction() { - public boolean luaStackCall(LuaState vm) { - vm.resettop(); - try { - vm.pushlvalue(freadline(f)); - } catch (IOException e) { - seterrorresult(vm,e); - } - return false; - } - }; - } - - private static void iowrite(LuaState vm, File f) throws IOException { - for ( int i=1, n=vm.gettop(); i<=n; i++ ) - f.write( vm.checklstring(i) ); - vm.resettop(); - vm.pushboolean(true); - } - - private static void ioread(LuaState vm, File f) throws IOException { - int i,n=vm.gettop(); - for ( i=1; i<=n; i++ ) { - if ( vm.isnumber(i) ) { - vm.pushlvalue(freadbytes(f,vm.tointeger(i))); - } else { - String format = vm.checkstring(i); - if ( "*n".equals(format) ) - vm.pushnumber(freadnumber(f)); - else if ( "*a".equals(format) ) - vm.pushlvalue(freadall(f)); - else if ( "*l".equals(format) ) - vm.pushlvalue(freadline(f)); - else - vm.typerror( i, "(invalid format)" ); - } - } - for ( i=1; i<=n; i++ ) - vm.remove(1); - } - - private static File checkfile(LuaState vm, int index) { - File f = (File) vm.checkudata(index, File.class); - checkopen( vm, f ); - return f; - } - - private File optfile(LuaState vm, int index) { - Object u = vm.touserdata(index); - return (u instanceof File? (File) u: null); - } - - private static File checkopen(LuaState vm, File file) { - if ( file.isclosed() ) - vm.error("attempt to use a closed file"); - return file; - } - - private static void setresult(LuaState vm, File file) { - vm.settop(0); - vm.pushlvalue(touserdata(file)); - } - - private static LUserData touserdata(File file) { - return new LUserData(file, FILE_MT); - } - - private File ioopenfile(LuaState vm, String filename, String mode) { - try { - return rawopenfile(filename, mode); - } catch ( Exception e ) { - vm.error("io error: "+e.getMessage()); - return null; - } - } - - private File rawopenfile(String filename, String mode) throws IOException { - boolean isstdfile = "-".equals(filename); - boolean isreadmode = mode.startsWith("r"); - if ( isstdfile ) { - return isreadmode? - wrapStdin(): - wrapStdout(); - } - boolean isappend = mode.startsWith("a"); - boolean isupdate = mode.indexOf("+") > 0; - boolean isbinary = mode.endsWith("b"); - return openFile( filename, isreadmode, isappend, isupdate, isbinary ); - } - - - // ------------- file reading utilitied ------------------ - - public static LValue freadbytes(File f, int count) throws IOException { - byte[] b = new byte[count]; - int r; - if ( ( r = f.read(b,0,b.length) ) < 0 ) - return LNil.NIL; - return new LString(b, 0, r); - } - public static LValue freaduntil(File f,int delim) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int c; - try { - while ( true ) { - c = f.read(); - if ( c < 0 || c == delim ) - break; - baos.write(c); - } - } catch ( EOFException e ) { - c = -1; - } - return ( c < 0 && baos.size() == 0 )? - (LValue) LNil.NIL: - (LValue) new LString(baos.toByteArray()); - } - public static LValue freadline(File f) throws IOException { - return freaduntil(f,'\n'); - } - public static LValue freadall(File f) throws IOException { - int n = f.remaining(); - if ( n >= 0 ) { - return freadbytes(f, n); - } else { - return freaduntil(f,-1); - } - } - public static Double freadnumber(File f) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - freadchars(f," \t\r\n",null); - freadchars(f,"-+",baos); - //freadchars(f,"0",baos); - //freadchars(f,"xX",baos); - freadchars(f,"0123456789",baos); - freadchars(f,".",baos); - freadchars(f,"0123456789",baos); - //freadchars(f,"eEfFgG",baos); - // freadchars(f,"+-",baos); - //freadchars(f,"0123456789",baos); - String s = baos.toString(); - return s.length()>0? Double.valueOf(s): null; - } - private static void freadchars(File f, String chars, ByteArrayOutputStream baos) throws IOException { - int c; - while ( true ) { - c = f.peek(); - if ( chars.indexOf(c) < 0 ) { - return; - } - f.read(); - if ( baos != null ) - baos.write( c ); - } - } - - - -} diff --git a/src/core/org/luaj/lib/LBuffer.java b/src/core/org/luaj/lib/LBuffer.java deleted file mode 100644 index bcbec925..00000000 --- a/src/core/org/luaj/lib/LBuffer.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import org.luaj.vm.LString; - -public class LBuffer { - - private byte[] bytes; - private int length; - - public LBuffer( int initialCapacity ) { - bytes = new byte[ initialCapacity ]; - length = 0; - } - - public void append( byte b ) { - ensureCapacity( length + 1 ); - bytes[ length++ ] = b; - } - - public void append( LString str ) { - final int alen = str.length(); - ensureCapacity( length + alen ); - str.copyInto( 0, bytes, length, alen ); - length += alen; - } - - public void append( String str ) { - final int alen = LString.lengthAsUtf8( str ); - ensureCapacity( length + alen ); - LString.encodeToUtf8( str, bytes, length ); - length += alen; - } - - public void setLength( int length ) { - ensureCapacity( length ); - this.length = length; - } - - public LString toLuaString() { - return new LString( realloc( bytes, length ) ); - } - - public void ensureCapacity( int minSize ) { - if ( minSize > bytes.length ) - realloc( minSize ); - } - - private void realloc( int minSize ) { - bytes = realloc( bytes, Math.max( bytes.length * 2, minSize ) ); - } - - private static byte[] realloc( byte[] b, int newSize ) { - byte[] newBytes = new byte[ newSize ]; - System.arraycopy( b, 0, newBytes, 0, Math.min( b.length, newSize ) ); - return newBytes; - } -} diff --git a/src/core/org/luaj/lib/MathLib.java b/src/core/org/luaj/lib/MathLib.java deleted file mode 100644 index cffa5c1b..00000000 --- a/src/core/org/luaj/lib/MathLib.java +++ /dev/null @@ -1,227 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import java.util.Random; - -import org.luaj.vm.LDouble; -import org.luaj.vm.LFunction; -import org.luaj.vm.LTable; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - - -public class MathLib extends LFunction { - - public static final String[] NAMES = { - "math", - - // irregular functions - "max", - "min", - "modf", - "ceil", - "floor", - "frexp", - "ldexp", - "random", - "randomseed", - - // 2 argument, return double - "atan2", - "fmod", - "pow", - - // single argument, return double - "abs", - "acos", - "asin", - "atan", - "cos", - "cosh", - "deg", - "exp", - "log", - "log10", - "rad", - "sin", - "sinh", - "sqrt", - "tan", - "tanh", - }; - - private static final int INSTALL = 0; - - // irregular functions - public static final int MAX = 1; - public static final int MIN = 2; - public static final int MODF = 3; - public static final int CEIL = 4; - public static final int FLOOR = 5; - public static final int FREXP = 6; - public static final int LDEXP = 7; - public static final int RANDOM = 8; - public static final int RSEED = 9; - public static final int LAST_IRREGULAR = RSEED; - - // 2 argument, return double - public static final int ATAN2 = 10; - public static final int FMOD = 11; - public static final int POW = 12; - public static final int LAST_DOUBLE_ARG = POW; - - /* Math operations - single argument, one function */ - public static final int ABS = 13; - public static final int ACOS = 14; - public static final int ASIN = 15; - public static final int ATAN = 16; - public static final int COS = 17; - public static final int COSH = 18; - public static final int DEG = 19; - public static final int EXP = 20; - public static final int LOG = 21; - public static final int LOG10 = 22; - public static final int RAD = 23; - public static final int SIN = 24; - public static final int SINH = 25; - public static final int SQRT = 26; - public static final int TAN = 27; - public static final int TANH = 28; - - private static Platform platform; - - public static void install( LTable globals ) { - LTable math = new LTable(); - for ( int i=1; i LAST_DOUBLE_ARG ) { - vm.pushlvalue( platform.mathop(id, vm.checknumber(1) ) ); - return 1; - } else if ( id > LAST_IRREGULAR ) { - vm.pushlvalue( platform.mathop(id, vm.checknumber(1), vm.checknumber(2) ) ); - return 1; - } else { - switch ( id ) { - case INSTALL: - install( vm._G ); - return 0; - case MAX: { - int n = vm.gettop(); - double x = vm.checkdouble(1); - for ( int i=2; i<=n; i++ ) - x = Math.max(x, vm.checkdouble(i)); - vm.pushnumber( x ); - return 1; - } - case MIN: { - int n = vm.gettop(); - double x = vm.checkdouble(1); - for ( int i=2; i<=n; i++ ) - x = Math.min(x, vm.checkdouble(i)); - vm.pushnumber( x ); - return 1; - } - case MODF: { - double x = vm.checkdouble(1); - double intPart = ( x > 0 ) ? Math.floor( x ) : Math.ceil( x ); - double fracPart = x - intPart; - vm.pushnumber( intPart ); - vm.pushnumber( fracPart ); - return 2; - } - case CEIL: - vm.pushnumber( Math.ceil( vm.checkdouble(1) ) ); - return 1; - case FLOOR: - vm.pushnumber( Math.floor( vm.checkdouble(1) ) ); - return 1; - case FREXP: { - long bits = Double.doubleToLongBits( vm.checkdouble(1) ); - vm.pushnumber( ((bits & (~(-1L<<52))) + (1L<<52)) * ((bits >= 0)? (.5 / (1L<<52)): (-.5 / (1L<<52))) ); - vm.pushinteger( (((int) (bits >> 52)) & 0x7ff) - 1022 ); - return 2; - } - case LDEXP: { - double m = vm.checkdouble(1); - int e = vm.checkint(2); - vm.pushnumber( m * Double.longBitsToDouble(((long)(e+1023)) << 52) ); - return 1; - } - case RANDOM: { - if ( random == null ) - random = new Random(1); - switch ( vm.gettop() ) { - case 0: - vm.pushnumber(random.nextDouble()); - return 1; - case 1: { - int m = vm.checkint(1); - vm.argcheck(1<=m, 1, "interval is empty"); - vm.pushinteger(1+random.nextInt(m)); - return 1; - } - default: { - int m = vm.checkint(1); - int n = vm.checkint(2); - vm.argcheck(m<=n, 2, "interval is empty"); - vm.pushinteger(m+random.nextInt(n+1-m)); - return 1; - } - } - } - case RSEED: - random = new Random( vm.checkint(1) ); - return 0; - default: - LuaState.vmerror( "bad math id" ); - return 0; - } - } - } -} diff --git a/src/core/org/luaj/lib/OsLib.java b/src/core/org/luaj/lib/OsLib.java deleted file mode 100644 index 591b58c9..00000000 --- a/src/core/org/luaj/lib/OsLib.java +++ /dev/null @@ -1,344 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2009 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import java.io.IOException; - -import org.luaj.vm.LFunction; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.LuaState; - -/** - * Base implementation of OsLib, with simplified stub functions - * for library functions that cannot be implemented uniformly - * on J2se and J2me. - * - * This can be installed as-is on either platform, or extended - * and refined to be used in a complete J2se implementation. - */ -public class OsLib extends LFunction { - public static String TMP_PREFIX = ".luaj"; - public static String TMP_SUFFIX = "tmp"; - - /** - * Create a function stub with a specific index. - * This is a factory method so that subclasses can - * use install(LTable,OsLib) to install themselves. - */ - protected OsLib newInstance( int index ) { - return new OsLib(index); - } - - public static final String[] NAMES = { - "os", - "clock", - "date", - "difftime", - "execute", - "exit", - "getenv", - "remove", - "rename", - "setlocale", - "time", - "tmpname", - }; - - private static final int INSTALL = 0; - private static final int CLOCK = 1; - private static final int DATE = 2; - private static final int DIFFTIME = 3; - private static final int EXECUTE = 4; - private static final int EXIT = 5; - private static final int GETENV = 6; - private static final int REMOVE = 7; - private static final int RENAME = 8; - private static final int SETLOCALE = 9; - private static final int TIME = 10; - private static final int TMPNAME = 11; - - /** - * Install the os library using the OsLib class as a factory - */ - public static void install( LTable globals ) { - install(globals, new OsLib()); - } - - /** - * Initialize the os libaray using the subblied instance as a factory. - * @param factory instance to use as a factory for function stubs. - */ - public static void install( LTable globals, OsLib factory ) { - LTable os = new LTable(); - for ( int i=CLOCK; i<=TMPNAME; i++ ) - os.put(NAMES[i], factory.newInstance(i)); - globals.put( "os", os ); - PackageLib.setIsLoaded("os", os); - } - - private static final long t0 = System.currentTimeMillis(); - private static long tmpnames = t0; - - private final int id; - - protected OsLib() { - id = 0; - } - - protected OsLib( int id ) { - this.id = id; - } - - public LString luaAsString() { - return new LString(toJavaString()); - } - - public String toJavaString() { - return "os."+toString(); - } - - public String toString() { - return NAMES[id]+"()"; - } - - public int invoke( LuaState vm ) { - LValue v; - long t,t2; - int c; - String s; - try { - switch ( id ) { - case INSTALL: - install(vm._G, this); - return 0; - case CLOCK: - vm.pushnumber(clock()); - return 1; - case DATE: - s = vm.optstring(1, null); - t = vm.optlong(2,-1); - vm.pushlvalue( date(s, t==-1? System.currentTimeMillis(): t) ); - return 1; - case DIFFTIME: - t2 = vm.checklong(1); - t = vm.checklong(2); - vm.pushnumber(difftime(t2,t)); - return 1; - case EXECUTE: - c = execute(vm.optstring(1, null)); - vm.pushinteger(c); - return 1; - case EXIT: - exit(vm.optint(1, 0)); - return 0; - case GETENV: - s = getenv(vm.checkstring(1)); - vm.pushstring(s); - return 1; - case REMOVE: - remove(vm.checkstring(1)); - vm.pushboolean(true); - return 1; - case RENAME: - rename(vm.checkstring(1), vm.checkstring(2)); - vm.pushboolean(true); - return 1; - case SETLOCALE: - s = setlocale(vm.optstring(1,null), vm.optstring(2, "all")); - if ( s != null ) - vm.pushstring(s); - else - vm.pushnil(); - return 1; - case TIME: - t = time(vm.isnoneornil(1)? null: vm.checktable(1)); - vm.pushnumber(t); - return 1; - case TMPNAME: - vm.pushstring(tmpname()); - return 1; - default: - LuaState.vmerror( "bad os id" ); - return 0; - } - } catch ( IOException e ) { - vm.pushnil(); - vm.pushstring(e.getMessage()); - return 2; - } - } - - /** - * @return an approximation of the amount in seconds of CPU time used by - * the program. - */ - protected double clock() { - return (System.currentTimeMillis()-t0) / 1000.; - } - - /** - * Returns the number of seconds from time t1 to time t2. - * In POSIX, Windows, and some other systems, this value is exactly t2-t1. - * @param t2 - * @param t1 - * @return diffeence in time values, in seconds - */ - protected double difftime(long t2, long t1) { - return (t2 - t1) / 1000.; - } - - /** - * If the time argument is present, this is the time to be formatted - * (see the os.time function for a description of this value). - * Otherwise, date formats the current time. - * - * If format starts with '!', then the date is formatted in Coordinated - * Universal Time. After this optional character, if format is the string - * "*t", then date returns a table with the following fields: year - * (four digits), month (1--12), day (1--31), hour (0--23), min (0--59), - * sec (0--61), wday (weekday, Sunday is 1), yday (day of the year), - * and isdst (daylight saving flag, a boolean). - * - * If format is not "*t", then date returns the date as a string, - * formatted according to the same rules as the C function strftime. - * - * When called without arguments, date returns a reasonable date and - * time representation that depends on the host system and on the - * current locale (that is, os.date() is equivalent to os.date("%c")). - * - * @param format - * @param time time since epoch, or -1 if not supplied - * @return a LString or a LTable containing date and time, - * formatted according to the given string format. - */ - protected LValue date(String format, long time) { - return LString.valueOf( new java.util.Date(time).toString() ); - } - - /** - * This function is equivalent to the C function system. - * It passes command to be executed by an operating system shell. - * It returns a status code, which is system-dependent. - * If command is absent, then it returns nonzero if a shell - * is available and zero otherwise. - * @param command command to pass to the system - */ - protected int execute(String command) { - return 0; - } - - /** - * Calls the C function exit, with an optional code, to terminate the host program. - * @param code - */ - protected void exit(int code) { - System.exit(code); - } - - /** - * Returns the value of the process environment variable varname, - * or null if the variable is not defined. - * @param varname - * @return - */ - protected String getenv(String varname) { - return System.getProperty(varname); - } - - /** - * Deletes the file or directory with the given name. - * Directories must be empty to be removed. - * If this function fails, it throws and IOException - * - * @param filename - * @throws IOException if it fails - */ - protected void remove(String filename) throws IOException { - throw new IOException( "not implemented" ); - } - - /** - * Renames file or directory named oldname to newname. - * If this function fails,it throws and IOException - * - * @param oldname old file name - * @param newname new file name - * @throws IOException if it fails - */ - protected void rename(String oldname, String newname) throws IOException { - throw new IOException( "not implemented" ); - } - - /** - * Sets the current locale of the program. locale is a string specifying - * a locale; category is an optional string describing which category to change: - * "all", "collate", "ctype", "monetary", "numeric", or "time"; the default category - * is "all". - * - * If locale is the empty string, the current locale is set to an implementation- - * defined native locale. If locale is the string "C", the current locale is set - * to the standard C locale. - * - * When called with null as the first argument, this function only returns the - * name of the current locale for the given category. - * - * @param locale - * @param category - * @return the name of the new locale, or null if the request - * cannot be honored. - */ - protected String setlocale(String locale, String category) { - return null; - } - - /** - * Returns the current time when called without arguments, - * or a time representing the date and time specified by the given table. - * This table must have fields year, month, and day, - * and may have fields hour, min, sec, and isdst - * (for a description of these fields, see the os.date function). - * @param table - * @return long value for the time - */ - protected long time(LTable table) { - return System.currentTimeMillis(); - } - - /** - * Returns a string with a file name that can be used for a temporary file. - * The file must be explicitly opened before its use and explicitly removed - * when no longer needed. - * - * On some systems (POSIX), this function also creates a file with that name, - * to avoid security risks. (Someone else might create the file with wrong - * permissions in the time between getting the name and creating the file.) - * You still have to open the file to use it and to remove it (even if you - * do not use it). - * - * @return String filename to use - */ - protected String tmpname() { - return TMP_PREFIX+(tmpnames++)+TMP_SUFFIX; - } -} diff --git a/src/core/org/luaj/lib/PackageLib.java b/src/core/org/luaj/lib/PackageLib.java deleted file mode 100644 index 57061895..00000000 --- a/src/core/org/luaj/lib/PackageLib.java +++ /dev/null @@ -1,416 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import java.io.InputStream; -import java.io.PrintStream; -import java.util.Vector; - -import org.luaj.vm.CallInfo; -import org.luaj.vm.LBoolean; -import org.luaj.vm.LFunction; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - - -public class PackageLib extends LFunction { - - public static String DEFAULT_LUA_PATH = "?.lua"; - - public static InputStream STDIN = null; - public static PrintStream STDOUT = System.out; - public static LTable LOADED = null; - - private static final LString _M = new LString("_M"); - private static final LString _NAME = new LString("_NAME"); - private static final LString _PACKAGE = new LString("_PACKAGE"); - private static final LString _DOT = new LString("."); - private static final LString _EMPTY = new LString(""); - private static final LString __INDEX = new LString("__index"); - private static final LString _LOADERS = new LString("loaders"); - private static final LString _PRELOAD = new LString("preload"); - private static final LString _PATH = new LString("path"); - private static final LValue _SENTINEL = _EMPTY; - - private static final String[] NAMES = { - "package", - "module", - "require", - "loadlib", - "seeall", - "preload_loader", - "lua_loader", - "java_loader", - }; - - private static final int INSTALL = 0; - private static final int MODULE = 1; - private static final int REQUIRE = 2; - private static final int LOADLIB = 3; - private static final int SEEALL = 4; - private static final int PRELOAD_LOADER = 5; - private static final int LUA_LOADER = 6; - private static final int JAVA_LOADER = 7; - - // all functions in package share this environment - private static LTable pckg; - - public static void install( LTable globals ) { - for ( int i=1; i<=REQUIRE; i++ ) - globals.put( NAMES[i], new PackageLib(i) ); - pckg = new LTable(); - for ( int i=LOADLIB; i<=SEEALL; i++ ) - pckg.put( NAMES[i], new PackageLib(i) ); - LOADED = new LTable(); - pckg.put( "loaded", LOADED ); - pckg.put( _PRELOAD, new LTable() ); - LTable loaders = new LTable(3,0); - for ( int i=PRELOAD_LOADER; i<=JAVA_LOADER; i++ ) - loaders.luaInsertPos(0, new PackageLib(i) ); - pckg.put( "loaders", loaders ); - pckg.put( _PATH, new LString(DEFAULT_LUA_PATH) ); - globals.put( "package", pckg ); - setIsLoaded( "package", pckg ); - } - - /** Allow packages to mark themselves as loaded */ - public static void setIsLoaded(String name, LTable value) { - LOADED.put(name, value); - } - - public static void setLuaPath( String newLuaPath ) { - pckg.put( _PATH, new LString(newLuaPath) ); - } - - private final int id; - - private PackageLib( int id ) { - this.id = id; - } - - public String toString() { - return NAMES[id]+"()"; - } - - public int invoke( LuaState vm ) { - switch ( id ) { - case INSTALL: - install(vm._G); - return 0; - case MODULE: - return module(vm); - case REQUIRE: - return require(vm); - case LOADLIB: - return loadlib(vm); - case SEEALL: { - LTable t = vm.checktable(1); - LTable m = t.luaGetMetatable(); - if ( m == null ) - t.luaSetMetatable(m = new LTable()); - m.put(__INDEX, vm._G); - return 0; - } - case PRELOAD_LOADER: { - return loader_preload(vm); - } - case LUA_LOADER: { - return loader_Lua(vm); - } - case JAVA_LOADER: { - return loader_Java(vm); - } - default: - LuaState.vmerror( "bad package id" ); - return 0; - } - } - - - // ======================== Module, Package loading ============================= - /** - * module (name [, ...]) - * - * Creates a module. If there is a table in package.loaded[name], this table - * is the module. Otherwise, if there is a global table t with the given - * name, this table is the module. Otherwise creates a new table t and sets - * it as the value of the global name and the value of package.loaded[name]. - * This function also initializes t._NAME with the given name, t._M with the - * module (t itself), and t._PACKAGE with the package name (the full module - * name minus last component; see below). Finally, module sets t as the new - * environment of the current function and the new value of - * package.loaded[name], so that require returns t. - * - * If name is a compound name (that is, one with components separated by - * dots), module creates (or reuses, if they already exist) tables for each - * component. For instance, if name is a.b.c, then module stores the module - * table in field c of field b of global a. - * - * This function may receive optional options after the module name, where - * each option is a function to be applied over the module. - */ - public static int module(LuaState vm) { - LString modname = vm.checklstring(1); - int n = vm.gettop(); - LValue value = LOADED.luaGetTable(vm, modname); - LTable module; - if ( ! value.isTable() ) { /* not found? */ - - /* try global variable (and create one if it does not exist) */ - module = findtable( vm._G, modname ); - if ( module == null ) - vm.error( "name conflict for module '"+modname+"'" ); - LOADED.luaSetTable(vm, modname, module); - } else { - module = (LTable) value; - } - - - /* check whether table already has a _NAME field */ - LValue name = module.luaGetTable(vm, _NAME); - if ( name.isNil() ) { - modinit( vm, module, modname ); - } - - // set the environment of the current function - CallInfo ci = vm.getStackFrame(0); - ci.closure.env = module; - - // apply the functions - for ( int i=2; i<=n; i++ ) { - vm.pushvalue( i ); /* get option (a function) */ - vm.pushlvalue( module ); /* module */ - vm.call( 1, 0 ); - } - - // returns no results - return 0; - } - - /** - * - * @param table the table at which to start the search - * @param fname the name to look up or create, such as "abc.def.ghi" - * @return the table for that name, possible a new one, or null if a non-table has that name already. - */ - private static LTable findtable(LTable table, LString fname) { - int b, e=(-1); - do { - e = fname.indexOf(_DOT, b=e+1 ); - if ( e < 0 ) - e = fname.m_length; - LString key = fname.substring(b, e); - LValue val = table.get(key); - if ( val.isNil() ) { /* no such field? */ - LTable field = new LTable(); /* new table for field */ - table.put(key, field); - table = field; - } else if ( val.luaGetType() != Lua.LUA_TTABLE ) { /* field has a non-table value? */ - return null; - } else { - table = (LTable) val; - } - } while ( e < fname.m_length ); - return table; - } - - private static void modinit(LuaState vm, LTable module, LString modname) { - /* module._M = module */ - module.luaSetTable(vm, _M, module); - int e = modname.lastIndexOf(_DOT); - module.luaSetTable(vm, _NAME, modname ); - module.luaSetTable(vm, _PACKAGE, (e<0? _EMPTY: modname.substring(0,e+1)) ); - } - - /** - * require (modname) - * - * Loads the given module. The function starts by looking into the package.loaded table to - * determine whether modname is already loaded. If it is, then require returns the value - * stored at package.loaded[modname]. Otherwise, it tries to find a loader for the module. - * - * To find a loader, require is guided by the package.loaders array. By changing this array, - * we can change how require looks for a module. The following explanation is based on the - * default configuration for package.loaders. - * - * First require queries package.preload[modname]. If it has a value, this value - * (which should be a function) is the loader. Otherwise require searches for a Lua loader - * using the path stored in package.path. If that also fails, it searches for a C loader - * using the path stored in package.cpath. If that also fails, it tries an all-in-one loader - * (see package.loaders). - * - * Once a loader is found, require calls the loader with a single argument, modname. - * If the loader returns any value, require assigns the returned value to package.loaded[modname]. - * If the loader returns no value and has not assigned any value to package.loaded[modname], - * then require assigns true to this entry. In any case, require returns the final value of - * package.loaded[modname]. - * - * If there is any error loading or running the module, or if it cannot find any loader for - * the module, then require signals an error. - */ - public int require( LuaState vm ) { - LString name = vm.checklstring(1); - LValue loaded = LOADED.luaGetTable(vm, name); - if ( loaded.toJavaBoolean() ) { - if ( loaded == _SENTINEL ) - vm.error("loop or previous error loading module '"+name+"'"); - vm.pushlvalue( loaded ); - return 1; - } - - /* else must load it; iterate over available loaders */ - LValue val = pckg.luaGetTable(vm, _LOADERS); - if ( ! val.isTable() ) - vm.error( "'package.loaders' must be a table" ); - LTable tbl = (LTable) val; - Vector v = new Vector(); - for ( int i=1; true; i++ ) { - LValue loader = tbl.get(i); - if ( loader.isNil() ) { - vm.error( "module '"+name+"' not found: "+v ); - } - /* call loader with module name as argument */ - vm.pushlvalue(loader); - vm.pushlstring(name); - vm.call(1, 1); - if ( vm.isfunction(-1) ) - break; /* module loaded successfully */ - if ( vm.isstring(-1) ) /* loader returned error message? */ - v.addElement(vm.tolstring(-1)); /* accumulate it */ - vm.pop(1); - } - - // load the module using the loader - LOADED.luaSetTable(vm, name, _SENTINEL); - vm.pushlstring( name ); /* pass name as argument to module */ - vm.call( 1, 1 ); /* run loaded module */ - if ( ! vm.isnil(-1) ) /* non-nil return? */ - LOADED.luaSetTable(vm, name, vm.topointer(-1) ); /* _LOADED[name] = returned value */ - LValue result = LOADED.luaGetTable(vm, name); - if ( result == _SENTINEL ) { /* module did not set a value? */ - LOADED.luaSetTable(vm, name, result=LBoolean.TRUE ); /* _LOADED[name] = true */ - } - vm.pushlvalue(result); - return 1; - } - - public static int loadlib( LuaState vm ) { - vm.checkstring(1); - vm.pushnil(); - vm.pushstring("dynamic libraries not enabled"); - vm.pushstring("absent"); - return 3; - } - - - private int loader_preload( LuaState vm ) { - LString name = vm.tolstring(1); - LValue preload = pckg.luaGetTable(vm, _PRELOAD); - if ( ! preload.isTable() ) - vm.error("package.preload '"+name+"' must be a table"); - LValue val = preload.luaGetTable(vm, name); - if ( val.isNil() ) - vm.pushstring("\n\tno field package.preload['"+name+"']"); - else - vm.pushlvalue(val); - return 1; - } - - private int loader_Lua( LuaState vm ) { - String name = vm.tostring(1); - InputStream is = findfile( vm, name, _PATH ); - if ( is != null ) { - String filename = vm.tostring(-1); - if ( ! BaseLib.loadis(vm, is, filename) ) - loaderror( vm, filename ); - } - return 1; - } - - private int loader_Java( LuaState vm ) { - String name = vm.tostring(1); - Class c = null; - LValue v = null; - try { - c = Class.forName(name); - v = (LValue) c.newInstance(); - vm.pushlvalue( v ); - } catch ( ClassNotFoundException cnfe ) { - vm.pushstring("\n\tno class '"+name+"'" ); - } catch ( Exception e ) { - vm.pushstring("\n\tjava load failed on '"+name+"', "+e ); - } - return 1; - } - - private InputStream findfile(LuaState vm, String name, LString pname) { - Platform p = Platform.getInstance(); - LValue pkg = pckg.luaGetTable(vm, pname); - if ( ! pkg.isString() ) - vm.error("package."+pname+" must be a string"); - String path = pkg.toJavaString(); - int e = -1; - int n = path.length(); - StringBuffer sb = null; - name = name.replace('.','/'); - while ( e < n ) { - - // find next template - int b = e+1; - e = path.indexOf(';',b); - if ( e < 0 ) - e = path.length(); - String template = path.substring(b,e); - - // create filename - int q = template.indexOf('?'); - String filename = template; - if ( q >= 0 ) { - filename = template.substring(0,q) + name + template.substring(q+1); - } - - // try opening the file - InputStream is = p.openFile(filename); - if ( is != null ) { - vm.pushstring(filename); - return is; - } - - // report error - if ( sb == null ) - sb = new StringBuffer(); - sb.append( "\n\tno file '"+filename+"'"); - } - - // not found, push error on stack and return - vm.pushstring(sb.toString()); - return null; - } - - private static void loaderror(LuaState vm, String filename) { - vm.error( "error loading module '"+vm.tostring(1)+"' from file '"+filename+"':\n\t"+vm.tostring(-1) ); - } -} diff --git a/src/core/org/luaj/lib/StringLib.java b/src/core/org/luaj/lib/StringLib.java deleted file mode 100644 index 6e3e983b..00000000 --- a/src/core/org/luaj/lib/StringLib.java +++ /dev/null @@ -1,1212 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.luaj.compiler.DumpState; -import org.luaj.vm.LClosure; -import org.luaj.vm.LFunction; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaState; - - -public class StringLib extends LFunction { - - private static final String[] NAMES = { - "string", - "byte", - "char", - "dump", - "find", - "format", - "gmatch", - "gsub", - "len", - "lower", - "match", - "rep", - "reverse", - "sub", - "upper", - }; - - private static final int INSTALL = 0; - private static final int BYTE = 1; - private static final int CHAR = 2; - private static final int DUMP = 3; - private static final int FIND = 4; - private static final int FORMAT = 5; - private static final int GMATCH = 6; - private static final int GSUB = 7; - private static final int LEN = 8; - private static final int LOWER = 9; - private static final int MATCH = 10; - private static final int REP = 11; - private static final int REVERSE = 12; - private static final int SUB = 13; - private static final int UPPER = 14; - - public static void install( LTable globals ) { - LTable string = LString.getMetatable(); - for ( int i=1; i l) pose = l; - if (posi > pose) return 0; /* empty interval; return no values */ - n = (int)(pose - posi + 1); - if (posi + n <= pose) /* overflow? */ - vm.error("string slice too long"); - vm.checkstack(n); - for (i=0; i=0 && c<256), a, "invalid value"); - bytes[i] = (byte) c; - } - vm.pushlstring( bytes ); - return 1; - } - - /** - * string.dump (function) - * - * Returns a string containing a binary representation of the given function, - * so that a later loadstring on this string returns a copy of the function. - * function must be a Lua function without upvalues. - * - * TODO: port dumping code as optional add-on - */ - static int dump( LuaState vm ) { - LFunction f = vm.checkfunction(1); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - DumpState.dump( ((LClosure)f).p, baos, true ); - vm.pushlstring(baos.toByteArray()); - return 1; - } catch (IOException e) { - vm.error( e.getMessage() ); - return 0; - } - } - - /** - * string.find (s, pattern [, init [, plain]]) - * - * Looks for the first match of pattern in the string s. - * If it finds a match, then find returns the indices of s - * where this occurrence starts and ends; otherwise, it returns nil. - * A third, optional numerical argument init specifies where to start the search; - * its default value is 1 and may be negative. A value of true as a fourth, - * optional argument plain turns off the pattern matching facilities, - * so the function does a plain "find substring" operation, - * with no characters in pattern being considered "magic". - * Note that if plain is given, then init must be given as well. - * - * If the pattern has captures, then in a successful match the captured values - * are also returned, after the two indices. - */ - static int find( LuaState vm ) { - return str_find_aux( vm, true ); - } - - /** - * string.format (formatstring, ...) - * - * Returns a formatted version of its variable number of arguments following - * the description given in its first argument (which must be a string). - * The format string follows the same rules as the printf family of standard C functions. - * The only differences are that the options/modifiers *, l, L, n, p, and h are not supported - * and that there is an extra option, q. The q option formats a string in a form suitable - * to be safely read back by the Lua interpreter: the string is written between double quotes, - * and all double quotes, newlines, embedded zeros, and backslashes in the string are correctly - * escaped when written. For instance, the call - * string.format('%q', 'a string with "quotes" and \n new line') - * - * will produce the string: - * "a string with \"quotes\" and \ - * new line" - * - * The options c, d, E, e, f, g, G, i, o, u, X, and x all expect a number as argument, - * whereas q and s expect a string. - * - * This function does not accept string values containing embedded zeros, - * except as arguments to the q option. - */ - static int format( LuaState vm ) { - LString fmt = vm.checklstring( 1 ); - final int n = fmt.length(); - LBuffer result = new LBuffer(n); - int arg = 1; - - for ( int i = 0; i < n; ) { - int c = fmt.luaByte( i++ ); - if ( c != L_ESC ) { - result.append( (byte) c ); - } else if ( i < n ) { - if ( ( c = fmt.luaByte( i ) ) == L_ESC ) { - ++i; - result.append( (byte)L_ESC ); - } else { - arg++; - FormatDesc fdsc = new FormatDesc(vm, fmt, i ); - i += fdsc.length; - switch ( fdsc.conversion ) { - case 'c': - fdsc.format( result, (byte)vm.checkint( arg ) ); - break; - case 'i': - case 'd': - fdsc.format( result, vm.checkint( arg ) ); - break; - case 'o': - case 'u': - case 'x': - case 'X': - fdsc.format( result, vm.checklong( arg ) ); - break; - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - fdsc.format( result, vm.checkdouble( arg ) ); - break; - case 'q': - addquoted( result, vm.checklstring( arg ) ); - break; - case 's': { - LString s = vm.checklstring( arg ); - if ( fdsc.precision == -1 && s.length() >= 100 ) { - result.append( s ); - } else { - fdsc.format( result, s ); - } - } break; - default: - vm.error("invalid option '%"+(char)fdsc.conversion+"' to 'format'"); - break; - } - } - } - } - - vm.pushlstring( result.toLuaString() ); - return 1; - } - - private static void addquoted(LBuffer buf, LString s) { - int c; - buf.append( (byte) '"' ); - for ( int i = 0, n = s.length(); i < n; i++ ) { - switch ( c = s.luaByte( i ) ) { - case '"': case '\\': case '\n': - buf.append( (byte)'\\' ); - buf.append( (byte)c ); - break; - case '\r': - buf.append( "\\r" ); - break; - case '\0': - buf.append( "\\000" ); - break; - default: - buf.append( (byte) c ); - break; - } - } - buf.append( (byte) '"' ); - } - - private static final String FLAGS = "-+ #0"; - - private static class FormatDesc { - - private boolean leftAdjust; - private boolean zeroPad; - private boolean explicitPlus; - private boolean space; - private boolean alternateForm; - private static final int MAX_FLAGS = 5; - - private int width; - private int precision; - - public final int conversion; - public final int length; - - public FormatDesc(LuaState vm, LString strfrmt, final int start) { - int p = start, n = strfrmt.length(); - int c = 0; - - boolean moreFlags = true; - while ( moreFlags ) { - switch ( c = ( (p < n) ? strfrmt.luaByte( p++ ) : 0 ) ) { - case '-': leftAdjust = true; break; - case '+': explicitPlus = true; break; - case ' ': space = true; break; - case '#': alternateForm = true; break; - case '0': zeroPad = true; break; - default: moreFlags = false; break; - } - } - if ( p - start > MAX_FLAGS ) - vm.error("invalid format (repeated flags)"); - - width = -1; - if ( Character.isDigit( (char)c ) ) { - width = c - '0'; - c = ( (p < n) ? strfrmt.luaByte( p++ ) : 0 ); - if ( Character.isDigit( (char) c ) ) { - width = width * 10 + (c - '0'); - c = ( (p < n) ? strfrmt.luaByte( p++ ) : 0 ); - } - } - - precision = -1; - if ( c == '.' ) { - c = ( (p < n) ? strfrmt.luaByte( p++ ) : 0 ); - if ( Character.isDigit( (char) c ) ) { - precision = c - '0'; - c = ( (p < n) ? strfrmt.luaByte( p++ ) : 0 ); - if ( Character.isDigit( (char) c ) ) { - precision = precision * 10 + (c - '0'); - c = ( (p < n) ? strfrmt.luaByte( p++ ) : 0 ); - } - } - } - - if ( Character.isDigit( (char) c ) ) - vm.error("invalid format (width or precision too long)"); - - zeroPad &= !leftAdjust; // '-' overrides '0' - conversion = c; - length = p - start; - } - - public void format(LBuffer buf, byte c) { - // TODO: not clear that any of width, precision, or flags apply here. - buf.append(c); - } - - public void format(LBuffer buf, long number) { - String digits; - - if ( number == 0 && precision == 0 ) { - digits = ""; - } else { - int radix; - switch ( conversion ) { - case 'x': - case 'X': - radix = 16; - break; - case 'o': - radix = 8; - break; - default: - radix = 10; - break; - } - digits = Long.toString( number, radix ); - if ( conversion == 'X' ) - digits = digits.toUpperCase(); - } - - int minwidth = digits.length(); - int ndigits = minwidth; - int nzeros; - - if ( number < 0 ) { - ndigits--; - } else if ( explicitPlus || space ) { - minwidth++; - } - - if ( precision > ndigits ) - nzeros = precision - ndigits; - else if ( precision == -1 && zeroPad && width > minwidth ) - nzeros = width - minwidth; - else - nzeros = 0; - - minwidth += nzeros; - int nspaces = width > minwidth ? width - minwidth : 0; - - if ( !leftAdjust ) - pad( buf, ' ', nspaces ); - - if ( number < 0 ) { - if ( nzeros > 0 ) { - buf.append( (byte)'-' ); - digits = digits.substring( 1 ); - } - } else if ( explicitPlus ) { - buf.append( (byte)'+' ); - } else if ( space ) { - buf.append( (byte)' ' ); - } - - if ( nzeros > 0 ) - pad( buf, '0', nzeros ); - - buf.append( digits ); - - if ( leftAdjust ) - pad( buf, ' ', nspaces ); - } - - public void format(LBuffer buf, double x) { - // TODO - buf.append( String.valueOf( x ) ); - } - - public void format(LBuffer buf, LString s) { - int nullindex = s.indexOf( (byte)'\0', 0 ); - if ( nullindex != -1 ) - s = s.substring( 0, nullindex ); - buf.append(s); - } - - public static final void pad(LBuffer buf, char c, int n) { - byte b = (byte)c; - while ( n-- > 0 ) - buf.append(b); - } - } - - /** - * string.gmatch (s, pattern) - * - * Returns an iterator function that, each time it is called, returns the next captures - * from pattern over string s. If pattern specifies no captures, then the - * whole match is produced in each call. - * - * As an example, the following loop - * s = "hello world from Lua" - * for w in string.gmatch(s, "%a+") do - * print(w) - * end - * - * will iterate over all the words from string s, printing one per line. - * The next example collects all pairs key=value from the given string into a table: - * t = {} - * s = "from=world, to=Lua" - * for k, v in string.gmatch(s, "(%w+)=(%w+)") do - * t[k] = v - * end - * - * For this function, a '^' at the start of a pattern does not work as an anchor, - * as this would prevent the iteration. - */ - static int gmatch( LuaState vm ) { - LString src = vm.checklstring( 1 ); - LString pat = vm.checklstring( 2 ); - vm.pushlvalue( new GMatchAux(vm, src, pat) ); - return 1; - } - - static class GMatchAux extends LFunction { - private final int srclen; - private final MatchState ms; - private int soffset; - public GMatchAux(LuaState vm, LString src, LString pat) { - this.srclen = src.length(); - this.ms = new MatchState(vm, src, pat); - this.soffset = 0; - } - public int invoke(LuaState vm) { - vm.resettop(); - for ( ; soffset=0 ) { - int soff = soffset; - soffset = res; - ms.push_captures( true, soff, res ); - return -1; - } - } - vm.pushnil(); - return 1; - } - } - - - /** - * string.gsub (s, pattern, repl [, n]) - * Returns a copy of s in which all (or the first n, if given) occurrences of the - * pattern have been replaced by a replacement string specified by repl, which - * may be a string, a table, or a function. gsub also returns, as its second value, - * the total number of matches that occurred. - * - * If repl is a string, then its value is used for replacement. - * The character % works as an escape character: any sequence in repl of the form %n, - * with n between 1 and 9, stands for the value of the n-th captured substring (see below). - * The sequence %0 stands for the whole match. The sequence %% stands for a single %. - * - * If repl is a table, then the table is queried for every match, using the first capture - * as the key; if the pattern specifies no captures, then the whole match is used as the key. - * - * If repl is a function, then this function is called every time a match occurs, - * with all captured substrings passed as arguments, in order; if the pattern specifies - * no captures, then the whole match is passed as a sole argument. - * - * If the value returned by the table query or by the function call is a string or a number, - * then it is used as the replacement string; otherwise, if it is false or nil, - * then there is no replacement (that is, the original match is kept in the string). - * - * Here are some examples: - * x = string.gsub("hello world", "(%w+)", "%1 %1") - * --> x="hello hello world world" - * - * x = string.gsub("hello world", "%w+", "%0 %0", 1) - * --> x="hello hello world" - * - * x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1") - * --> x="world hello Lua from" - * - * x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv) - * --> x="home = /home/roberto, user = roberto" - * - * x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s) - * return loadstring(s)() - * end) - * --> x="4+5 = 9" - * - * local t = {name="lua", version="5.1"} - * x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t) - * --> x="lua-5.1.tar.gz" - */ - static int gsub( LuaState vm ) { - LString src = vm.checklstring( 1 ); - final int srclen = src.length(); - LString p = vm.checklstring( 2 ); - LValue repl = vm.topointer( 3 ); - int max_s = vm.optint( 4, srclen + 1 ); - final boolean anchor = p.length() > 0 && p.charAt( 0 ) == '^'; - - LBuffer lbuf = new LBuffer( srclen ); - MatchState ms = new MatchState( vm, src, p ); - - int soffset = 0; - int n = 0; - while ( n < max_s ) { - ms.reset(); - int res = ms.match( soffset, anchor ? 1 : 0 ); - if ( res != -1 ) { - n++; - ms.add_value( lbuf, soffset, res, repl ); - } - if ( res != -1 && res > soffset ) - soffset = res; - else if ( soffset < srclen ) - lbuf.append( (byte) src.luaByte( soffset++ ) ); - else - break; - if ( anchor ) - break; - } - lbuf.append( src.substring( soffset, srclen ) ); - vm.pushlstring( lbuf.toLuaString() ); - vm.pushinteger( n ); - return 2; - } - - /** - * string.len (s) - * - * Receives a string and returns its length. The empty string "" has length 0. - * Embedded zeros are counted, so "a\000bc\000" has length 5. - */ - static int len( LuaState vm ) { - vm.pushinteger( vm.checklstring(1).length() ); - return 1; - } - - /** - * string.lower (s) - * - * Receives a string and returns a copy of this string with all uppercase letters - * changed to lowercase. All other characters are left unchanged. - * The definition of what an uppercase letter is depends on the current locale. - */ - static int lower( LuaState vm ) { - vm.pushstring( vm.checkstring(1).toLowerCase() ); - return 1; - } - - /** - * string.match (s, pattern [, init]) - * - * Looks for the first match of pattern in the string s. If it finds one, - * then match returns the captures from the pattern; otherwise it returns - * nil. If pattern specifies no captures, then the whole match is returned. - * A third, optional numerical argument init specifies where to start the - * search; its default value is 1 and may be negative. - */ - static int match( LuaState vm ) { - return str_find_aux( vm, false ); - } - - /** - * string.rep (s, n) - * - * Returns a string that is the concatenation of n copies of the string s. - */ - static int rep( LuaState vm ) { - LString s = vm.checklstring( 1 ); - int n = vm.checkint( 2 ); - final byte[] bytes = new byte[ s.length() * n ]; - int len = s.length(); - for ( int offset = 0; offset < bytes.length; offset += len ) { - s.copyInto( 0, bytes, offset, len ); - } - vm.pushlstring( bytes ); - return 1; - } - - /** - * string.reverse (s) - * - * Returns a string that is the string s reversed. - */ - static int reverse( LuaState vm ) { - LString s = vm.checklstring(1); - int n = s.length(); - byte[] b = new byte[n]; - for ( int i=0, j=n-1; i l ) - end = l; - - vm.resettop(); - if ( start <= end ) { - LString result = s.substring( start-1 , end ); - vm.pushlstring( result ); - } else { - vm.pushstring( "" ); - } - return 1; - } - - /** - * string.upper (s) - * - * Receives a string and returns a copy of this string with all lowercase letters - * changed to uppercase. All other characters are left unchanged. - * The definition of what a lowercase letter is depends on the current locale. - */ - static int upper( LuaState vm ) { - vm.pushstring(vm.checkstring(1).toUpperCase()); - return 1; - } - - /** - * This utility method implements both string.find and string.match. - */ - static int str_find_aux( LuaState vm, boolean find ) { - LString s = vm.checklstring( 1 ); - LString pat = vm.checklstring( 2 ); - int init = vm.optint( 3, 1 ); - - if ( init > 0 ) { - init = Math.min( init - 1, s.length() ); - } else if ( init < 0 ) { - init = Math.max( 0, s.length() + init ); - } - - boolean fastMatch = find && ( vm.toboolean( 4 ) || pat.indexOfAny( SPECIALS ) == -1 ); - - if ( fastMatch ) { - int result = s.indexOf( pat, init ); - if ( result != -1 ) { - vm.pushinteger( result + 1 ); - vm.pushinteger( result + pat.length() ); - return 2; - } - } else { - MatchState ms = new MatchState( vm, s, pat ); - - boolean anchor = false; - int poff = 0; - if ( pat.luaByte( 0 ) == '^' ) { - anchor = true; - poff = 1; - } - - int soff = init; - vm.resettop(); - do { - int res; - ms.reset(); - if ( ( res = ms.match( soff, poff ) ) != -1 ) { - if ( find ) { - vm.pushinteger( soff + 1 ); - vm.pushinteger( res ); - ms.push_captures( false, soff, res ); - } else { - ms.push_captures( true, soff, res ); - } - return -1; - } - } while ( soff++ < s.length() && !anchor ); - } - vm.pushnil(); - return 1; - } - - private static int posrelat( int pos, int len ) { - return ( pos >= 0 ) ? pos : len + pos + 1; - } - - // Pattern matching implementation - - private static final int L_ESC = '%'; - private static final LString SPECIALS = new LString("^$*+?.([%-"); - private static final int MAX_CAPTURES = 32; - - private static final int CAP_UNFINISHED = -1; - private static final int CAP_POSITION = -2; - - private static final byte MASK_ALPHA = 0x01; - private static final byte MASK_LOWERCASE = 0x02; - private static final byte MASK_UPPERCASE = 0x04; - private static final byte MASK_DIGIT = 0x08; - private static final byte MASK_PUNCT = 0x10; - private static final byte MASK_SPACE = 0x20; - private static final byte MASK_CONTROL = 0x40; - private static final byte MASK_HEXDIGIT = (byte)0x80; - - private static final byte[] CHAR_TABLE; - - static { - CHAR_TABLE = new byte[256]; - - for ( int i = 0; i < 256; ++i ) { - final char c = (char) i; - CHAR_TABLE[i] = (byte)( ( Character.isDigit( c ) ? MASK_DIGIT : 0 ) | - ( Character.isLowerCase( c ) ? MASK_LOWERCASE : 0 ) | - ( Character.isUpperCase( c ) ? MASK_UPPERCASE : 0 ) | - ( ( c < ' ' || c == 0x7F ) ? MASK_CONTROL : 0 ) ); - if ( ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) || ( c >= '0' && c <= '9' ) ) { - CHAR_TABLE[i] |= MASK_HEXDIGIT; - } - if ( ( c >= '!' && c <= '/' ) || ( c >= ':' && c <= '@' ) ) { - CHAR_TABLE[i] |= MASK_PUNCT; - } - if ( ( CHAR_TABLE[i] & ( MASK_LOWERCASE | MASK_UPPERCASE ) ) != 0 ) { - CHAR_TABLE[i] |= MASK_ALPHA; - } - } - - CHAR_TABLE[' '] = MASK_SPACE; - CHAR_TABLE['\r'] |= MASK_SPACE; - CHAR_TABLE['\n'] |= MASK_SPACE; - CHAR_TABLE['\t'] |= MASK_SPACE; - CHAR_TABLE[0x0C /* '\v' */ ] |= MASK_SPACE; - CHAR_TABLE['\f'] |= MASK_SPACE; - }; - - private static class MatchState { - final LString s; - final LString p; - final LuaState vm; - int level; - int[] cinit; - int[] clen; - - MatchState( LuaState vm, LString s, LString pattern ) { - this.s = s; - this.p = pattern; - this.vm = vm; - this.level = 0; - this.cinit = new int[ MAX_CAPTURES ]; - this.clen = new int[ MAX_CAPTURES ]; - } - - void reset() { - level = 0; - } - - private void add_s( LBuffer lbuf, LString news, int soff, int e ) { - int l = news.length(); - for ( int i = 0; i < l; ++i ) { - byte b = (byte) news.luaByte( i ); - if ( b != L_ESC ) { - lbuf.append( (byte) b ); - } else { - ++i; // skip ESC - b = (byte) news.luaByte( i ); - if ( !Character.isDigit( (char) b ) ) { - lbuf.append( b ); - } else if ( b == '0' ) { - lbuf.append( s.substring( soff, e ) ); - } else { - push_onecapture( b - '1', soff, e ); - lbuf.append( vm.topointer( -1 ).luaAsString() ); - vm.pop( 1 ); - } - } - } - } - - public void add_value( LBuffer lbuf, int soffset, int end, LValue repl ) { - switch ( repl.luaGetType() ) { - case Lua.LUA_TSTRING: - case Lua.LUA_TNUMBER: - add_s( lbuf, repl.luaAsString(), soffset, end ); - return; - - case Lua.LUA_TFUNCTION: - vm.pushlvalue( repl ); - int n = push_captures( true, soffset, end ); - vm.call( n, 1 ); - break; - - case Lua.LUA_TTABLE: - // Need to call push_onecapture here for the error checking - push_onecapture( 0, soffset, end ); - LValue k = vm.topointer( -1 ); - vm.pop( 1 ); - vm.pushlvalue( ((LTable) repl).luaGetTable( vm, k ) ); - break; - - default: - vm.error( "bad argument: string/function/table expected" ); - return; - } - - repl = vm.topointer( -1 ); - if ( !repl.toJavaBoolean() ) { - repl = s.substring( soffset, end ); - } else if ( ! repl.isString() ) { - vm.error( "invalid replacement value (a "+repl.luaGetTypeName()+")" ); - } - vm.pop( 1 ); - lbuf.append( repl.luaAsString() ); - } - - int push_captures( boolean wholeMatch, int soff, int end ) { - int nlevels = ( this.level == 0 && wholeMatch ) ? 1 : this.level; - for ( int i = 0; i < nlevels; ++i ) { - push_onecapture( i, soff, end ); - } - return nlevels; - } - - private void push_onecapture( int i, int soff, int end ) { - if ( i >= this.level ) { - if ( i == 0 ) { - vm.pushlstring( s.substring( soff, end ) ); - } else { - vm.error( "invalid capture index" ); - } - } else { - int l = clen[i]; - if ( l == CAP_UNFINISHED ) { - vm.error( "unfinished capture" ); - } - if ( l == CAP_POSITION ) { - vm.pushinteger( cinit[i] + 1 ); - } else { - int begin = cinit[i]; - vm.pushlstring( s.substring( begin, begin + l ) ); - } - } - } - - private int check_capture( int l ) { - l -= '1'; - if ( l < 0 || l >= level || this.clen[l] == CAP_UNFINISHED ) { - vm.error("invalid capture index"); - } - return l; - } - - private int capture_to_close() { - int level = this.level; - for ( level--; level >= 0; level-- ) - if ( clen[level] == CAP_UNFINISHED ) - return level; - vm.error("invalid pattern capture"); - return 0; - } - - int classend( int poffset ) { - switch ( p.luaByte( poffset++ ) ) { - case L_ESC: - if ( poffset == p.length() ) { - vm.error( "malformed pattern (ends with %)" ); - } - return poffset + 1; - - case '[': - if ( p.luaByte( poffset ) == '^' ) poffset++; - do { - if ( poffset == p.length() ) { - vm.error( "malformed pattern (missing ])" ); - } - if ( p.luaByte( poffset++ ) == L_ESC && poffset != p.length() ) - poffset++; - } while ( p.luaByte( poffset ) != ']' ); - return poffset + 1; - default: - return poffset; - } - } - - static boolean match_class( int c, int cl ) { - final char lcl = Character.toLowerCase( (char) cl ); - int cdata = CHAR_TABLE[c]; - - boolean res; - switch ( lcl ) { - case 'a': res = ( cdata & MASK_ALPHA ) != 0; break; - case 'd': res = ( cdata & MASK_DIGIT ) != 0; break; - case 'l': res = ( cdata & MASK_LOWERCASE ) != 0; break; - case 'u': res = ( cdata & MASK_UPPERCASE ) != 0; break; - case 'c': res = ( cdata & MASK_CONTROL ) != 0; break; - case 'p': res = ( cdata & MASK_PUNCT ) != 0; break; - case 's': res = ( cdata & MASK_SPACE ) != 0; break; - case 'w': res = ( cdata & ( MASK_ALPHA | MASK_DIGIT ) ) != 0; break; - case 'x': res = ( cdata & MASK_HEXDIGIT ) != 0; break; - case 'z': res = ( c == 0 ); break; - default: return cl == c; - } - return ( lcl == cl ) ? res : !res; - } - - boolean matchbracketclass( int c, int poff, int ec ) { - boolean sig = true; - if ( p.luaByte( poff + 1 ) == '^' ) { - sig = false; - poff++; - } - while ( ++poff < ec ) { - if ( p.luaByte( poff ) == L_ESC ) { - poff++; - if ( match_class( c, p.luaByte( poff ) ) ) - return sig; - } - else if ( ( p.luaByte( poff + 1 ) == '-' ) && ( poff + 2 < ec ) ) { - poff += 2; - if ( p.luaByte( poff - 2 ) <= c && c <= p.luaByte( poff ) ) - return sig; - } - else if ( p.luaByte( poff ) == c ) return sig; - } - return !sig; - } - - boolean singlematch( int c, int poff, int ep ) { - switch ( p.luaByte( poff ) ) { - case '.': return true; - case L_ESC: return match_class( c, p.luaByte( poff + 1 ) ); - case '[': return matchbracketclass( c, poff, ep - 1 ); - default: return p.luaByte( poff ) == c; - } - } - - /** - * Perform pattern matching. If there is a match, returns offset into s - * where match ends, otherwise returns -1. - */ - int match( int soffset, int poffset ) { - while ( true ) { - // Check if we are at the end of the pattern - - // equivalent to the '\0' case in the C version, but our pattern - // string is not NUL-terminated. - if ( poffset == p.length() ) - return soffset; - switch ( p.luaByte( poffset ) ) { - case '(': - if ( ++poffset < p.length() && p.luaByte( poffset ) == ')' ) - return start_capture( soffset, poffset + 1, CAP_POSITION ); - else - return start_capture( soffset, poffset, CAP_UNFINISHED ); - case ')': - return end_capture( soffset, poffset + 1 ); - case L_ESC: - if ( poffset + 1 == p.length() ) - vm.error("malformed pattern (ends with '%')"); - switch ( p.luaByte( poffset + 1 ) ) { - case 'b': - soffset = matchbalance( soffset, poffset + 2 ); - if ( soffset == -1 ) return -1; - poffset += 4; - continue; - case 'f': { - poffset += 2; - if ( p.luaByte( poffset ) != '[' ) { - vm.error("Missing [ after %f in pattern"); - } - int ep = classend( poffset ); - int previous = ( soffset == 0 ) ? -1 : s.luaByte( soffset - 1 ); - if ( matchbracketclass( previous, poffset, ep - 1 ) || - matchbracketclass( s.luaByte( soffset ), poffset, ep - 1 ) ) - return -1; - poffset = ep; - continue; - } - default: { - int c = p.luaByte( poffset + 1 ); - if ( Character.isDigit( (char) c ) ) { - soffset = match_capture( soffset, c ); - if ( soffset == -1 ) - return -1; - return match( soffset, poffset + 2 ); - } - } - } - case '$': - if ( poffset + 1 == p.length() ) - return ( soffset == s.length() ) ? soffset : -1; - } - int ep = classend( poffset ); - boolean m = soffset < s.length() && singlematch( s.luaByte( soffset ), poffset, ep ); - int pc = ( ep < p.length() ) ? p.luaByte( ep ) : '\0'; - - switch ( pc ) { - case '?': - int res; - if ( m && ( ( res = match( soffset + 1, ep + 1 ) ) != -1 ) ) - return res; - poffset = ep + 1; - continue; - case '*': - return max_expand( soffset, poffset, ep ); - case '+': - return ( m ? max_expand( soffset + 1, poffset, ep ) : -1 ); - case '-': - return min_expand( soffset, poffset, ep ); - default: - if ( !m ) - return -1; - soffset++; - poffset = ep; - continue; - } - } - } - - int max_expand( int soff, int poff, int ep ) { - int i = 0; - while ( soff + i < s.length() && - singlematch( s.luaByte( soff + i ), poff, ep ) ) - i++; - while ( i >= 0 ) { - int res = match( soff + i, ep + 1 ); - if ( res != -1 ) - return res; - i--; - } - return -1; - } - - int min_expand( int soff, int poff, int ep ) { - for ( ;; ) { - int res = match( soff, ep + 1 ); - if ( res != -1 ) - return res; - else if ( soff < s.length() && singlematch( s.luaByte( soff ), poff, ep ) ) - soff++; - else return -1; - } - } - - int start_capture( int soff, int poff, int what ) { - int res; - int level = this.level; - if ( level >= MAX_CAPTURES ) { - vm.error( "too many captures" ); - } - cinit[ level ] = soff; - clen[ level ] = what; - this.level = level + 1; - if ( ( res = match( soff, poff ) ) == -1 ) - this.level--; - return res; - } - - int end_capture( int soff, int poff ) { - int l = capture_to_close(); - int res; - clen[l] = soff - cinit[l]; - if ( ( res = match( soff, poff ) ) == -1 ) - clen[l] = CAP_UNFINISHED; - return res; - } - - int match_capture( int soff, int l ) { - l = check_capture( l ); - int len = clen[ l ]; - if ( ( s.length() - soff ) >= len && - LString.equals( s, cinit[l], s, soff, len ) ) - return soff + len; - else - return -1; - } - - int matchbalance( int soff, int poff ) { - final int plen = p.length(); - if ( poff == plen || poff + 1 == plen ) { - vm.error( "unbalanced pattern" ); - } - if ( s.luaByte( soff ) != p.luaByte( poff ) ) - return -1; - else { - int b = p.luaByte( poff ); - int e = p.luaByte( poff + 1 ); - int cont = 1; - while ( ++soff < s.length() ) { - if ( s.luaByte( soff ) == e ) { - if ( --cont == 0 ) return soff + 1; - } - else if ( s.luaByte( soff ) == b ) cont++; - } - } - return -1; - } - } -} diff --git a/src/core/org/luaj/lib/TableLib.java b/src/core/org/luaj/lib/TableLib.java deleted file mode 100644 index 0dbdd3f2..00000000 --- a/src/core/org/luaj/lib/TableLib.java +++ /dev/null @@ -1,210 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib; - -import java.io.ByteArrayOutputStream; - -import org.luaj.vm.LFunction; -import org.luaj.vm.LNil; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.LuaState; - - -public class TableLib extends LFunction { - - public static final String[] NAMES = { - "table", - "concat", - "foreach", - "foreachi", - "getn", - "insert", - "maxn", - "remove", - "sort", - }; - - private static final int INSTALL = 0; - private static final int CONCAT = 1; - private static final int FOREACH = 2; - private static final int FOREACHI = 3; - private static final int GETN = 4; - private static final int INSERT = 5; - private static final int MAXN = 6; - private static final int REMOVE = 7; - private static final int SORT = 8; - - public static void install( LTable globals ) { - LTable table = new LTable(); - for ( int i=1; i= 0 ) { - LValue v = vm.stack[base + a]; - if ( v.isFunction() ) - return (LFunction) v; - } - return null; - } - - /** - * @param vm - * @return register of the current function executing, or null - */ - public int currentfunca(LuaState vm) { - int i = closure.p.code[currentpc()]; - int op = Lua.GET_OPCODE(i); - if ( op == Lua.OP_CALL || op == Lua.OP_TAILCALL ) - return Lua.GETARG_A(i); - return -1; - } - - /** - * Get current program counter or instruction being executed now. - */ - public int currentpc() { - return pc>0? pc-1: 0; - } - -} diff --git a/src/core/org/luaj/vm/DebugNetSupport.java b/src/core/org/luaj/vm/DebugNetSupport.java deleted file mode 100644 index 36f7e082..00000000 --- a/src/core/org/luaj/vm/DebugNetSupport.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.luaj.vm; - -import java.io.IOException; - -public interface DebugNetSupport { - - /** - * Starts the networking for debug support. - * @throws IOException - */ - public abstract void start() throws IOException; - - /** - * Shuts down the networking for the debug support. - */ - public abstract void stop(); - - /** - * Disconnect all connected clients. - */ - public abstract void disconnect(); -} \ No newline at end of file diff --git a/src/core/org/luaj/vm/LBoolean.java b/src/core/org/luaj/vm/LBoolean.java deleted file mode 100644 index d04d4691..00000000 --- a/src/core/org/luaj/vm/LBoolean.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - -public final class LBoolean extends LValue { - - public static final LBoolean TRUE = new LBoolean("true",true); - - public static final LBoolean FALSE = new LBoolean("false",false); - - private final String m_sname; - private final LString m_name; - private final boolean m_value; - - private LBoolean( String name, boolean value ) { - this.m_sname = name; - this.m_name = new LString( name ); - this.m_value = value; - } - - public final String toJavaString() { - return m_sname; - } - - public final LString luaAsString() { - return m_name; - } - - public final boolean toJavaBoolean() { - return m_value; - } - - public final int toJavaInt() { - return m_value? 1: 0; - } - - public final static LBoolean valueOf(boolean value) { - return value? TRUE: FALSE; - } - - public int luaGetType() { - return Lua.LUA_TBOOLEAN; - } -} diff --git a/src/core/org/luaj/vm/LClosure.java b/src/core/org/luaj/vm/LClosure.java deleted file mode 100644 index 4d9dc60f..00000000 --- a/src/core/org/luaj/vm/LClosure.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - - -public class LClosure extends LFunction { - public LPrototype p; - public UpVal[] upVals; - public LTable env; - - - /** - * Construct using a prototype and initial environment. - * @param p - * @param env - */ - protected LClosure(LPrototype p, LTable env) { - this.p = p; - this.env = env; - upVals = new UpVal[p.nups]; - } - - // called by vm when there is an OP_CALL - // in this case, we are on the stack, - // and simply need to cue the VM to treat it as a stack call - public boolean luaStackCall(LuaState vm) { - vm.prepStackCall(); - return true; - } - - /** Set the environment if a thread, or closure, and return 1, otherwise return 0 */ - public boolean luaSetEnv(LTable t) { - this.env = t; - return true; - } - - /** Get the enviroment for this closure */ - public LTable luaGetEnv(LTable d) { - return env; - } - - /** Returns true if this is a lua closure, false otherwise */ - public boolean isClosure() { - return true; - } - -} diff --git a/src/core/org/luaj/vm/LDouble.java b/src/core/org/luaj/vm/LDouble.java deleted file mode 100644 index 3e00c5e2..00000000 --- a/src/core/org/luaj/vm/LDouble.java +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - -public class LDouble extends LNumber { - - private final double m_value; - - public static LDouble valueOf(double value) { - return new LDouble(value); - } - - /** Convert to LNumber, using LInteger if possible */ - public static LNumber numberOf(double z) { - int iz = (int) z; - return (z==iz? (LNumber) LInteger.valueOf(iz): (LNumber) new LDouble(z)); - } - - public LDouble(double value) { - this.m_value = value; - } - - public int hashCode() { - if ( m_value == 0 ) { - return 0; - } else { - int iz = (int) m_value; - if ( iz == m_value ) return iz; - long bits = Double.doubleToLongBits( m_value ); - return ((int) (bits >> 32)) + ((int)bits); - } - } - - public String toJavaString() { - if ( Double.isNaN(m_value) ) - return "nan"; - if ( Double.isInfinite(m_value) ) - return (m_value>0? "inf": "-inf"); - if ( m_value == 0.0 ) { - long bits = Double.doubleToLongBits( m_value ); - return ( bits >> 63 == 0 ) ? "0" : "-0"; - } - long l = (long) m_value; - if ( (m_value == (double) l) && (m_value <= Long.MAX_VALUE) && (m_value >= Long.MIN_VALUE) ) { - return Long.toString( l ); - } else { - return Double.toString( m_value ); - } - } - - // return true if value survives as an integer - public boolean isInteger() { - return ( (double) ( (int) m_value ) ) == m_value; - } - - // binary operations on integers, first dispatch - public LValue luaBinOpUnknown(int opcode, LValue lhs) { - return lhs.luaBinOpDouble( opcode, this.m_value ); - } - - // binary operations on mixtures of doubles and integers - public LValue luaBinOpInteger(int opcode, int rhs) { - return luaBinOpDoubleDouble( opcode, m_value, (double) rhs ); - } - - // binary operations on doubles - public LValue luaBinOpDouble(int opcode, double rhs) { - return luaBinOpDoubleDouble( opcode, m_value, rhs ); - } - - public static LValue luaBinOpDoubleDouble( int opcode, double lhs, double rhs ) { - switch ( opcode ) { - case Lua.OP_ADD: return LDouble.numberOf( lhs + rhs ); - case Lua.OP_SUB: return LDouble.numberOf( lhs - rhs ); - case Lua.OP_MUL: return LDouble.numberOf( lhs * rhs ); - case Lua.OP_DIV: return LDouble.numberOf( lhs / rhs ); - case Lua.OP_MOD: return LDouble.numberOf( lhs - Math.floor(lhs/rhs) * rhs ); - case Lua.OP_POW: return Platform.getInstance().mathPow( LDouble.numberOf(lhs), LDouble.numberOf(rhs)); - } - LuaState.vmerror( "bad bin opcode" ); - return null; - } - - public int toJavaInt() { - return (int) m_value; - } - - public long toJavaLong() { - return (long) m_value; - } - - public float toJavaFloat() { - return (float) m_value; - } - - public double toJavaDouble() { - return m_value; - } - - // binary compares on integers, first dispatch - public boolean luaBinCmpUnknown(int opcode, LValue lhs) { - return lhs.luaBinCmpDouble( opcode, this.m_value ); - } - - // binary compares on mixtures of doubles and integers - public boolean luaBinCmpInteger(int opcode, int rhs) { - return luaBinCmpDoubleDouble( opcode, m_value, (double) rhs ); - } - - // binary compares on doubles - public boolean luaBinCmpDouble(int opcode, double rhs) { - return luaBinCmpDoubleDouble( opcode, m_value, rhs ); - } - - // compare two doubles - public static boolean luaBinCmpDoubleDouble( int opcode, double lhs, double rhs ) { - switch ( opcode ) { - case Lua.OP_EQ: return lhs == rhs; - case Lua.OP_LT: return lhs < rhs; - case Lua.OP_LE: return lhs <= rhs; - } - LuaState.vmerror( "bad cmp opcode" ); - return false; - } - - /** Arithmetic negative */ - public LValue luaUnaryMinus() { - return new LDouble( -m_value ); - } -} diff --git a/src/core/org/luaj/vm/LFunction.java b/src/core/org/luaj/vm/LFunction.java deleted file mode 100644 index 33133707..00000000 --- a/src/core/org/luaj/vm/LFunction.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - -abstract -public class LFunction extends LValue { - - public String toJavaString() { - return "function: "+hashCode(); - } - - public boolean isFunction() { - return true; - } - - public int luaGetType() { - return Lua.LUA_TFUNCTION; - } - - /** - * Set up a Java invocation, and leave the results on the stack - * starting at base. The default implementation for LFunction - * delegates to the VM which provides convenience. - */ - public boolean luaStackCall(LuaState vm) { - vm.invokeJavaFunction( this ); - return false; - } - - /** - * Called to invoke a JavaFunction. - * - * The implementation should manipulate the stack - * via the VM Java API in the same way that lua_CFunctions - * do so in standard lua. - * - * Arguments to the function will be in position 1-n. - * Return values can be pushed onto the stack, and will be - * copied down to the appropriate location by the calling LuaState. - * - * - * @param lua the LuaState calling this function. - * @return number of results pushed onto the stack. - */ - public int invoke( LuaState lua ) { - return 0; - } - - /** - * Process lua tag method __index when it points to a function. - * Default method calls the function using the vm. - * - * @param vm - * @param table - * @param key - * @return - */ - public LValue __index(LuaState vm, LValue table, LValue key) { - return vm.luaV_call_index(this, table, key); - } - - /** - * Process lua tag method __newindex when it points to a function - * Default method calls the function using the vm. - * - * @param vm - * @param table - * @param key - * @param val - */ - public void __newindex(LuaState vm, LValue table, LValue key, LValue val) { - vm.luaV_call_newindex(this, table, key, val); - } - - -} diff --git a/src/core/org/luaj/vm/LInteger.java b/src/core/org/luaj/vm/LInteger.java deleted file mode 100644 index 2cb50f62..00000000 --- a/src/core/org/luaj/vm/LInteger.java +++ /dev/null @@ -1,136 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - -public class LInteger extends LNumber { - private final int m_value; - - /* local cache of commonly used LInteger values */ - private static final int INTS_MIN = -16; - private static final int INTS_MAX = 32; - private static final LInteger s_ints[] = new LInteger[1+INTS_MAX-INTS_MIN]; - static { - for ( int i=INTS_MIN; i<=INTS_MAX; i++ ) - s_ints[i-INTS_MIN] = new LInteger(i); - } - - /** Get an LInteger corresponding to a particular int value */ - public static LInteger valueOf(int n) { - if ( n >= INTS_MIN && n <= INTS_MAX ) - return s_ints[n-INTS_MIN]; - return new LInteger(n); - } - - /** use LInteger.valueOf() instead */ - private LInteger(int value) { - this.m_value = value; - } - - public final int hashCode() { - return hashCodeOf( m_value ); - } - - public static int hashCodeOf( int v ) { - return v; - } - - public int toJavaInt() { - return m_value; - } - - public long toJavaLong() { - return m_value; - } - - public float toJavaFloat() { - return m_value; - } - - public double toJavaDouble() { - return m_value; - } - - public LString luaAsString() { - return LString.valueOf(m_value); - } - - public String toJavaString() { - return String.valueOf(m_value); - } - - public boolean isInteger() { - return true; - } - - // binary operations on integers, first dispatch - public LValue luaBinOpUnknown(int opcode, LValue lhs) { - return lhs.luaBinOpInteger( opcode, this.m_value ); - } - - // binary operations on integers - public LValue luaBinOpInteger(int opcode, int rhs) { - switch ( opcode ) { - case Lua.OP_ADD: return LInteger.valueOf( m_value + rhs ); - case Lua.OP_SUB: return LInteger.valueOf( m_value - rhs ); - case Lua.OP_MUL: return LInteger.valueOf( m_value * rhs ); - case Lua.OP_DIV: - case Lua.OP_MOD: - case Lua.OP_POW: - return LDouble.luaBinOpDoubleDouble(opcode, m_value, rhs); - } - LuaState.vmerror( "bad bin opcode" ); - return null; - } - - // binary operations on mixed integer, double - public LValue luaBinOpDouble(int opcode, double rhs) { - return LDouble.luaBinOpDoubleDouble(opcode, (double) m_value, rhs ); - } - - // binary compare for integers, first dispatch - public boolean luaBinCmpUnknown(int opcode, LValue lhs) { - return lhs.luaBinCmpInteger( opcode, this.m_value ); - } - - // unsupported except for numbers - public boolean luaBinCmpInteger(int opcode, int rhs) { - switch ( opcode ) { - case Lua.OP_EQ: return m_value == rhs; - case Lua.OP_LT: return m_value < rhs; - case Lua.OP_LE: return m_value <= rhs; - } - LuaState.vmerror( "bad cmp opcode" ); - return false; - } - - // unsupported except for numbers - public boolean luaBinCmpDouble(int opcode, double rhs) { - return LDouble.luaBinCmpDoubleDouble(opcode, (double) m_value, rhs ); - } - - /** Arithmetic negative */ - public LValue luaUnaryMinus() { - return LInteger.valueOf( -m_value ); - } - -} diff --git a/src/core/org/luaj/vm/LNil.java b/src/core/org/luaj/vm/LNil.java deleted file mode 100644 index bf2ede16..00000000 --- a/src/core/org/luaj/vm/LNil.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - -public final class LNil extends LValue { - public static final LNil NIL = new LNil(); - - public final LString luaAsString() { - return luaGetTypeName(); - } - - public boolean isNil() { - return true; - } - - public boolean toJavaBoolean() { - return false; - } - - public int luaGetType() { - return Lua.LUA_TNIL; - } - - public int toJavaInt() { - return 0; - } - - public String toJavaString() { - return "nil"; - } - - public Byte toJavaBoxedByte() { - return null; - } - - public Character toJavaBoxedCharacter() { - return null; - } - - public Double toJavaBoxedDouble() { - return null; - } - - public Float toJavaBoxedFloat() { - return null; - } - - public Integer toJavaBoxedInteger() { - return null; - } - - public Long toJavaBoxedLong() { - return null; - } - - public Short toJavaBoxedShort() { - return null; - } - -} diff --git a/src/core/org/luaj/vm/LNumber.java b/src/core/org/luaj/vm/LNumber.java deleted file mode 100644 index 4aa550d1..00000000 --- a/src/core/org/luaj/vm/LNumber.java +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - -import java.io.ByteArrayOutputStream; - - -abstract -public class LNumber extends LValue { - - /** Compare for equivalence by using lua op comparator */ - public boolean equals(Object o) { - if ( ! ( o instanceof LValue) ) - return false; - LValue v = (LValue) o; - return this.luaBinCmpUnknown(Lua.OP_EQ, v ); - } - - public int luaGetType() { - return Lua.LUA_TNUMBER; - } - - /** - * Returns false by default for non-LNumbers, but subclasses of LNumber must - * override. - */ - public abstract boolean isInteger(); - - /** - * In lua all numbers are strings ! - */ - public boolean isString() { - return true; - } - - /** Convert to a Byte value */ - public Byte toJavaBoxedByte() { - return new Byte(toJavaByte()); - } - - /** Convert to a boxed Character value */ - public Character toJavaBoxedCharacter() { - return new Character(toJavaChar()); - } - - /** Convert to a boxed Double value */ - public Double toJavaBoxedDouble() { - return new Double(toJavaDouble()); - } - - /** Convert to a boxed Float value */ - public Float toJavaBoxedFloat() { - return new Float(toJavaFloat()); - } - - /** Convert to a boxed Integer value */ - public Integer toJavaBoxedInteger() { - return new Integer(toJavaInt()); - } - - /** Convert to a boxed Long value */ - public Long toJavaBoxedLong() { - return new Long(toJavaLong()); - } - - /** Convert to a boxed Short value */ - public Short toJavaBoxedShort() { - return new Short(toJavaShort()); - } - - /** Convert to a number if possible, or nil otherwise */ - public LValue luaToNumber() { - return this; - } - - /** Write as a string */ - public void luaConcatTo(ByteArrayOutputStream baos) { - luaAsString().luaConcatTo( baos ); - } - - /** Returns true if this is or can be made into a number */ - public boolean isNumber() { - return true; - } -} diff --git a/src/core/org/luaj/vm/LPrototype.java b/src/core/org/luaj/vm/LPrototype.java deleted file mode 100644 index 67eef1e7..00000000 --- a/src/core/org/luaj/vm/LPrototype.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - - -/* -** Function Prototypes -*/ -public class LPrototype { - public LPrototype() { - } - public LClosure newClosure(LTable env) { - return new LClosure(this,env); - } - - /* constants used by the function */ - public LValue[] k; - public int[] code; - /* functions defined inside the function */ - public LPrototype[] p; - /* map from opcodes to source lines */ - public int[] lineinfo; - /* information about local variables */ - public LocVars[] locvars; - /* upvalue names */ - public LString[] upvalues; - public LString source; - public int nups; - public int linedefined; - public int lastlinedefined; - public int numparams; - public int is_vararg; - public int maxstacksize; - - /** Get the name of a local variable. - * - * @param number the local variable number to look up - * @param pc the program counter - * @return the name, or null if not found - */ - public LString getlocalname(int number, int pc) { - int i; - for (i = 0; i=0||i>=j)? - b: - (b<-32||i+1>=j)? - (((b&0x3f) << 6) - | (m_bytes[i++]&0x3f)): - (((b&0xf) << 12) - | ((m_bytes[i++]&0x3f)<<6) - | (m_bytes[i++]&0x3f)) - ); - } - return new String(c,0,n); - } - - /** - * Construct a string from the given byte array. - * - * new LString(b) is identical to new LString(b, 0, b.length) - */ - public LString(byte[] bytes) { - this( bytes, 0, bytes.length ); - } - - /** - * Construct a string from the given byte array and range. For efficiency, - * the byte array is not copied. Lua strings are immutable so the bytes must - * not be modified after the string is constructed. - */ - public LString(byte[] bytes, int off, int len) { - if ( off < 0 || len < 0 || off+len > bytes.length ) - throw new IndexOutOfBoundsException(); - this.m_bytes = bytes; - this.m_offset = off; - this.m_length = len; - this.m_hash = hashBytes( bytes, off, len ); - } - - public static LString newStringCopy(LString src) { - return newStringCopy( src.m_bytes, src.m_offset, src.m_length ); - } - - public static LString newStringCopy(byte[] buf, int off, int len) { - byte[] b = new byte[len]; - System.arraycopy( buf, off, b, 0, len ); - return new LString( b, 0, len ); - } - - public static LString newStringNoCopy(byte[] buf, int off, int len) { - return new LString( buf, off, len ); - } - - /** - * Count the number of bytes required to encode the string as UTF-8. - */ - public static int lengthAsUtf8(String string) { - int n = string.length(); - int b = n; - char c; - for ( int i=0; i= 0x80 ) { - ++b; - if ( c >= 0x800 ) - ++b; - } - } - return b; - } - - /** - * Encode the given Java string as UTF-8 bytes, writing the result to bytes - * starting at offset. The string should be measured first with lengthAsUtf8 - * to make sure the given byte array is large enough. - */ - public static void encodeToUtf8(String string, byte[] bytes, final int startOffset) { - final int n = string.length(); - for ( int i=0, j=startOffset; i>6) & 0x1f)); - bytes[j++] = (byte) (0x80 | ( c & 0x3f)); - } else { - bytes[j++] = (byte) (0xE0 | ((c>>12) & 0x0f)); - bytes[j++] = (byte) (0x80 | ((c>>6) & 0x3f)); - bytes[j++] = (byte) (0x80 | ( c & 0x3f)); - } - } - } - - public boolean isString() { - return true; - } - - public boolean equals(Object o) { - if ( this == o ) - return true; - if ( o != null && o instanceof LString ) { - LString s = (LString) o; - if ( m_hash == s.m_hash && m_length == s.m_length ) { - if ( m_bytes == s.m_bytes && m_offset == s.m_offset ) - return true; - if ( equals( m_bytes, m_offset, s.m_bytes, s.m_offset, m_length ) ) { - if ( m_bytes.length < s.m_bytes.length ) { - s.m_bytes = m_bytes; - s.m_offset = m_offset; - } else { - m_bytes = s.m_bytes; - m_offset = s.m_offset; - } - return true; - } - } - } - return false; - } - - public int compareTo( LString o ) { - final byte[] a = this.m_bytes; - final byte[] b = o.m_bytes; - int i = this.m_offset; - int j = o.m_offset; - final int imax = i + m_length; - final int jmax = j + o.m_length; - - if ( a == b && i == j && imax == jmax ) - return 0; - - while ( i < imax && j < jmax ) { - if ( a[i] != b[j] ) { - return ( ( (int)a[i] ) & 0x0FF ) - ( ( (int)b[j] ) & 0x0FF ); - } - i++; - j++; - } - - return m_length - o.m_length; - } - - public int hashCode() { - return m_hash; - } - - public int length() { - return m_length; - } - - public LString substring( int beginIndex, int endIndex ) { - return new LString( m_bytes, m_offset + beginIndex, endIndex - beginIndex ); - } - - public int charAt( int index ) { - if ( index < 0 || index >= m_length ) - throw new IndexOutOfBoundsException(); - return luaByte( index ); - } - - /** Java version of strpbrk, which is a terribly named C function. */ - public int indexOfAny( LString accept ) { - final int ilimit = m_offset + m_length; - final int jlimit = accept.m_offset + accept.m_length; - for ( int i = m_offset; i < ilimit; ++i ) { - for ( int j = accept.m_offset; j < jlimit; ++j ) { - if ( m_bytes[i] == accept.m_bytes[j] ) { - return i - m_offset; - } - } - } - return -1; - } - - public int indexOf( byte b, int start ) { - for ( int i = m_offset + start; i < m_length; ++i ) { - if ( m_bytes[i] == b ) - return i; - } - return -1; - } - - public int indexOf( LString s, int start ) { - final int slen = s.length(); - final int limit = m_offset + m_length - slen; - for ( int i = m_offset + start; i <= limit; ++i ) { - if ( equals( m_bytes, i, s.m_bytes, s.m_offset, slen ) ) { - return i; - } - } - return -1; - } - - public int lastIndexOf( LString s ) { - final int slen = s.length(); - final int limit = m_offset + m_length - slen; - for ( int i = limit; i >= m_offset; --i ) { - if ( equals( m_bytes, i, s.m_bytes, s.m_offset, slen ) ) { - return i; - } - } - return -1; - } - - public static LString valueOf( double d ) { - return new LString( String.valueOf( d ) ); - } - - public static LString valueOf( int x ) { - return new LString( String.valueOf( x ) ); - } - - public static LString valueOf(String s) { - return new LString( s ); - } - - /** - * Write the specified substring of this string to the given output stream. - */ - public void write( OutputStream os, int offset, int len ) throws IOException { - if ( offset < 0 || len < 0 ) - throw new IndexOutOfBoundsException(); - if ( offset + len > m_length ) - throw new IndexOutOfBoundsException(); - - os.write( m_bytes, m_offset+offset, len ); - } - - public void write(OutputStream os) throws IOException { - write(os, 0, m_length); - } - - /** - * Copy the bytes of the string into the given byte array. - */ - public void copyInto( int strOffset, byte[] bytes, int arrayOffset, int len ) { - System.arraycopy( m_bytes, m_offset+strOffset, bytes, arrayOffset, len ); - } - - /** - * Produce an InputStream instance from which the bytes of this LString can be read. - * Underlying byte array is not copied. - */ - public ByteArrayInputStream toInputStream() { - // Well, this is really something. - // Javadoc for java versions 1.3 and earlier states that if reset() is - // called on a ByteArrayInputStream constructed with the 3-argument - // constructor, then bytes 0 .. offset will be returned by the next - // calls to read(). In JDK 1.4, the behavior improved, so that the - // initial mark is set to the initial offset. We still need to - // override ByteArrayInputStream here just in case we run on a - // JVM with the older behavior. - return new ByteArrayInputStream( m_bytes, m_offset, m_length ) { - public synchronized void reset() { - pos = Math.max( m_offset, mark ); - } - }; - } - - public boolean luaBinCmpUnknown(int opcode, LValue lhs) { - return lhs.luaBinCmpString(opcode, this); - } - - public boolean luaBinCmpString(int opcode, LString rhs) { - switch ( opcode ) { - case Lua.OP_EQ: return equals(rhs); - case Lua.OP_LT: return compareTo(rhs) < 0; - case Lua.OP_LE: return compareTo(rhs) <= 0; - } - LuaState.vmerror( "bad cmp opcode" ); - return false; - } - - public LValue luaBinOpDouble( int opcode, double m_value ) { - return luaToNumber().luaBinOpDouble( opcode, m_value ); - } - - public LValue luaBinOpInteger( int opcode, int m_value ) { - return luaToNumber().luaBinOpInteger( opcode, m_value ); - } - - public LValue luaBinOpUnknown( int opcode, LValue lhs ) { - return luaToNumber().luaBinOpUnknown( opcode, lhs ); - } - - public LValue luaUnaryMinus() { - return luaToNumber().luaUnaryMinus(); - } - - public LValue luaToNumber() { - return luaToNumber( 10 ); - } - - public LValue luaToNumber( int base ) { - if ( base >= 2 && base <= 36 ) { - String str = toJavaString().trim(); - if ( ( base == 10 || base == 16 ) && ( str.startsWith("0x") || str.startsWith("0X") ) ) { - base = 16; - str = str.substring(2); - } - try { - long x = Long.parseLong(str, base); - if (x < Integer.MIN_VALUE || x > Integer.MAX_VALUE) - return new LDouble((double) x); - else - return LInteger.valueOf((int) x); - } catch ( NumberFormatException nfe ) { - if ( base == 10 ) { - try { - return LDouble.numberOf( Double.parseDouble( str ) ); - } catch ( NumberFormatException nfe2 ) { - } - } - } - } - - return LNil.NIL; - } - - public LString luaAsString() { - return this; - } - - /** Built-in opcode LEN, for Strings and Tables */ - public int luaLength() { - return m_length; - } - - public int luaGetType() { - return Lua.LUA_TSTRING; - } - - public LTable luaGetMetatable() { - synchronized ( LString.class ) { - return s_stringMT; - } - } - - /** - * Get the metatable for all string values. Creates the table if it does not - * exist yet, and sets its __index entry to point to itself. - * - * @return metatable that will be used for all strings - */ - public static synchronized LTable getMetatable() { - if ( s_stringMT == null ) { - s_stringMT = new LTable(); - s_stringMT.put( TM_INDEX, s_stringMT ); - } - return s_stringMT; - } - - public static boolean equals( LString a, int i, LString b, int j, int n ) { - return equals( a.m_bytes, a.m_offset + i, b.m_bytes, b.m_offset + j, n ); - } - - public static boolean equals( byte[] a, int i, byte[] b, int j, int n ) { - if ( a.length < i + n || b.length < j + n ) - return false; - while ( --n>=0 ) - if ( a[i++]!=b[j++] ) - return false; - return true; - } - - private static int hashBytes( byte[] bytes, int offset, int length ) { - // Compute the hash of the given bytes. - // This code comes right out of Lua 5.1.2 (translated from C to Java) - int h = length; /* seed */ - int step = (length>>5)+1; /* if string is too long, don't hash all its chars */ - for (int l1=length; l1>=step; l1-=step) /* compute hash */ - h = h ^ ((h<<5)+(h>>2)+(((int) bytes[offset+l1-1] ) & 0x0FF )); - return h; - } - - public int luaByte(int index) { - return m_bytes[m_offset + index] & 0x0FF; - } - - public void luaConcatTo(ByteArrayOutputStream baos) { - baos.write( m_bytes, m_offset, m_length ); - } - - /** Returns true if this is or can be made into a number */ - public boolean isNumber() { - return ! this.luaToNumber().isNil(); - } - - -} diff --git a/src/core/org/luaj/vm/LTable.java b/src/core/org/luaj/vm/LTable.java deleted file mode 100644 index 409e0cdc..00000000 --- a/src/core/org/luaj/vm/LTable.java +++ /dev/null @@ -1,683 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - -import java.util.Vector; - -import org.luaj.vm.LFunction; -import org.luaj.vm.LInteger; -import org.luaj.vm.LNil; -import org.luaj.vm.LString; -import org.luaj.vm.LValue; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaErrorException; -import org.luaj.vm.LuaState; - -/** - * Simple implementation of table structure for Lua VM. Maintains both an array - * part and a hash part. Does not attempt to achieve the same performance as the - * C version. - * - * Java code can put values in the table or get values out (bypassing the - * metatable, if there is one) using put() and get(). There are specializations - * of put() and get() for integers and Strings to avoid allocating wrapper - * objects when possible. - * - * remove() methods are private: setting a key's value to nil is the correct way - * to remove an entry from the table. - * - * - */ -public class LTable extends LValue { - - protected Object[] array; - protected LValue[] hashKeys; - protected Object[] hashValues; - private int hashEntries; - private LTable m_metatable; - - private static final int MIN_HASH_CAPACITY = 2; - private static final LValue[] NONE = {}; - - - /** Construct an empty LTable with no initial capacity. */ - public LTable() { - array = NONE; - hashKeys = NONE; - } - - /** - * Construct an empty LTable that is expected to contain entries with keys - * in the range 1 .. narray and nhash non-integer keys. - */ - public LTable( int narray, int nhash ) { - if ( nhash > 0 && nhash < MIN_HASH_CAPACITY ) - nhash = MIN_HASH_CAPACITY; - array = new Object[narray]; - hashKeys = new LValue[nhash]; - hashValues = new Object[nhash]; - } - - public boolean isTable() { - return true; - - } - /** Get capacity of hash part */ - public int getArrayCapacity() { - return array.length; - } - - /** Get capacity of hash part */ - public int getHashCapacity() { - return hashKeys.length; - } - - /** - * Return total number of keys mapped to non-nil values. Not to be confused - * with luaLength, which returns some number n such that the value at n+1 is - * nil. - * - * @deprecated this is not scalable. Does a linear search through the table. Use luaLength() instead. - */ - public int size() { - int count = 0; - for ( int i=array.length; --i>=0; ) - if ( array[i] != null ) - count++; - for ( int i=hashKeys.length; --i>=0; ) - if ( hashKeys[i] != null ) - count++; - return count; - } - - /** - * Generic put method for all types of keys, but does not use the metatable. - */ - public void put( LValue key, LValue val ) { - if ( key.isInteger() ) { - int pos = key.toJavaInt() - 1; - int n = array.length; - if ( pos>=0 && pos<=n ) { - if ( pos == n ) - expandArrayPart(); - array[pos] = normalizePut(val); - return; - } - } - hashSet( key, normalizePut(val) ); - } - - /** - * Method for putting an integer-keyed value. Bypasses the metatable, if - * any. - */ - public void put( int key, LValue val ) { - int pos = key - 1; - int n = array.length; - if ( pos>=0 && pos<=n ) { - if ( pos == n ) - expandArrayPart(); - array[pos] = normalizePut(val); - } else { - hashSet( LInteger.valueOf(key), normalizePut(val) ); - } - } - - /** - * Utility method for putting a string-keyed value directly, typically for - * initializing a table. Bypasses the metatable, if any. - */ - public void put( String key, LValue val ) { - hashSet( LString.valueOf(key), normalizePut(val) ); - } - - /** - * Utility method for putting a string key, int value directly, typically for - * initializing a table. Bypasses the metatable, if any. - */ - public void put( String key, int val ) { - hashSet( LString.valueOf(key), LInteger.valueOf(val) ); - } - - /** - * Expand the array part of the backing for more values to fit in. - */ - private void expandArrayPart() { - int n = array.length; - int m = Math.max(2,n*2); - arrayExpand(m); - for ( int i=n; i0 && ikey<=array.length ) - return normalizeGet(array[ikey-1]); - } - return normalizeGet(hashGet(key)); - } - - - - /** Utility method for retrieving an integer-keyed value */ - public LValue get( int key ) { - return normalizeGet( key>0 && key<=array.length? - array[key-1]: - hashGet(LInteger.valueOf(key)) ); - } - - /** Check for null, and convert to nilor leave alone - */ - protected LValue normalizeGet(Object val) { - return val==null? LNil.NIL: (LValue) val; - } - - /** - * Return true if the table contains an entry with the given key, - * false if not. Ignores the metatable. - */ - public boolean containsKey( LValue key ) { - if ( key.isInteger() ) { - int ikey = key.toJavaInt(); - if ( ikey>0 && ikey<=array.length ) - return null != array[ikey-1]; - } - return null != hashGet(key); - } - - /** - * Return true if the table contains an entry with the given integer-valued key, - * false if not. Ignores the metatable. - */ - public boolean containsKey( int key ) { - return (key>0 && key<=array.length? - array[key-1] != null: - (hashKeys.length>0 && hashKeys[hashFindSlot(LInteger.valueOf(key))]!=null)); - } - - private static final int MAX_KEY = 0x3fffffff; - - /** - * Try to find a boundary in table `t'. A `boundary' is an integer index - * such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). - */ - public int luaLength() { - - // find `i' and `j' such that i is present and j is not - int i = 0; - int j = array.length; - if (j<=0 || containsKey(j)) { - if ( hashKeys.length == 0 ) - return j; - for ( ++j; containsKey(j) && j < MAX_KEY; j*=2 ) - i = j; - } - - // binary search - while ( j - i > 1) { - int m = (i+j) / 2; - if ( ! containsKey(m) ) - j = m; - else - i = m; - } - return i; - } - - /** Valid for tables */ - public LTable luaGetMetatable() { - return this.m_metatable; - } - - /** Valid for tables */ - public LTable luaSetMetatable(LValue metatable) { - if ( m_metatable != null && m_metatable.containsKey(TM_METATABLE) ) - throw new LuaErrorException("cannot change a protected metatable"); - if ( metatable == null || metatable.isNil() ) - this.m_metatable = null; - else if ( metatable.luaGetType() == Lua.LUA_TTABLE ) { - org.luaj.vm.LTable t = (org.luaj.vm.LTable) metatable; - LValue m = t.get(TM_MODE); - if ( m.isString() && m.toJavaString().indexOf('v')>=0 ) { - LTable w = new LWeakTable(this); - w.m_metatable = t; - return w; - } - this.m_metatable = t; - } else { - throw new LuaErrorException("not a table: "+metatable.luaGetTypeName()); - } - return this; - } - - public String toJavaString() { - return "table: "+id(); - } - - public int luaGetType() { - return Lua.LUA_TTABLE; - } - - /** - * Helper method to get all the keys in this table in an array. Meant to be - * used instead of keys() (which returns an enumeration) when an array is - * more convenient. Note that for a very large table, getting an Enumeration - * instead would be more space efficient. - * - * @deprecated this is not scalable. Does a linear search through the table. - */ - public LValue[] getKeys() { - int n = array.length; - int o = hashKeys.length; - LValue k; - Vector v = new Vector(); - - // array parts - for ( int pos=0; pos n ) - return LNil.NIL; - - LValue removed = get(ikey); - LValue replaced; - do { - put(ikey, replaced=get(ikey+1)); - ikey++; - } while ( ! replaced.isNil() ); - return removed; - } - - /** - * Returns the largest positive numerical index of the given table, - * or zero if the table has no positive numerical indices. - * (To do its job this function does a linear traversal of the whole table.) - * @return LValue that is the largest int - */ - public LValue luaMaxN() { - int n = array.length; - int m = hashKeys.length; - int r = Integer.MIN_VALUE; - - // array part - for ( int i=n; --i>=0; ) { - if ( array[i] != null ) { - r = i+1; - break; - } - } - - // hash part - for ( int i=0; i r ) - r = k; - } - } - - return LInteger.valueOf( r == Integer.MIN_VALUE? 0: r ); - } - - // ----------------- sort support ----------------------------- - // - // implemented heap sort from wikipedia - // - public void luaSort(LuaState vm, LValue compare) { - heapSort(luaLength(), vm, compare); - } - - private void heapSort(int count, LuaState vm, LValue cmpfunc) { - heapify(count, vm, cmpfunc); - for ( int end=count-1; end>0; ) { - swap(end, 0); - siftDown(0, --end, vm, cmpfunc); - } - } - - private void heapify(int count, LuaState vm, LValue cmpfunc) { - for ( int start=count/2-1; start>=0; --start ) - siftDown(start, count - 1, vm, cmpfunc); - } - - private void siftDown(int start, int end, LuaState vm, LValue cmpfunc) { - for ( int root=start; root*2+1 <= end; ) { - int child = root*2+1; - if (child < end && compare(child, child + 1, vm, cmpfunc)) - ++child; - if (compare(root, child, vm, cmpfunc)) { - swap(root, child); - root = child; - } else - return; - } - } - - private boolean compare(int i, int j, LuaState vm, LValue cmpfunc) { - LValue a = get(i+1); - LValue b = get(j+1); - if ( a.isNil() || b.isNil() ) - return false; - if ( ! cmpfunc.isNil() ) { - vm.pushlvalue(cmpfunc); - vm.pushlvalue(a); - vm.pushlvalue(b); - vm.call(2, 1); - boolean result = vm.toboolean(-1); - vm.resettop(); - return result; - } else { - return b.luaBinCmpUnknown( Lua.OP_LT, a ); - } - } - - private void swap(int i, int j) { - LValue a = get(i+1); - put(i+1, get(j+1)); - put(j+1, a); - } - - /** - * Leave key,value pair on top, or nil if at end of list. - * @param vm the LuaState to leave the values on - * @param indexedonly TODO - * @param index index to start search - * @return true if next exists, false if at end of list - */ - public boolean next(LuaState vm, LValue key, boolean indexedonly ) { - - int n = array.length; - int m = (indexedonly? -1: hashKeys.length); - int i = findindex(key, n, m); - if ( i < 0 ) - vm.error( "invalid key to 'next'" ); - - // check array part - for ( ; i 0 ) { - int slot = hashFindSlot( key ); - hashClearSlot( slot ); - } - } - - protected void hashClearSlot( int i ) { - if ( hashKeys[ i ] != null ) { - - int j = i; - int n = hashKeys.length; - while ( hashKeys[ j = ( ( j + 1 ) % n ) ] != null ) { - final int k = ( ( hashKeys[ j ].hashCode() )& 0x7FFFFFFF ) % n; - if ( ( j > i && ( k <= i || k > j ) ) || - ( j < i && ( k <= i && k > j ) ) ) { - hashKeys[ i ] = hashKeys[ j ]; - hashValues[ i ] = hashValues[ j ]; - i = j; - } - } - - --hashEntries; - hashKeys[ i ] = null; - hashValues[ i ] = null; - - if ( hashEntries == 0 ) { - hashKeys = NONE; - hashValues = null; - } - } - } - - protected boolean checkLoadFactor() { - // Using a load factor of 2/3 because that is easy to compute without - // overflow or division. - final int hashCapacity = hashKeys.length; - return ( hashCapacity >> 1 ) >= ( hashCapacity - hashEntries ); - } - - protected void rehash() { - final int oldCapacity = hashKeys.length; - final int newCapacity = ( oldCapacity > 0 ) ? 2 * oldCapacity : MIN_HASH_CAPACITY; - - final LValue[] oldKeys = hashKeys; - final Object[] oldValues = hashValues; - - hashKeys = new LValue[ newCapacity ]; - hashValues = new Object[ newCapacity ]; - - for ( int i = 0; i < oldCapacity; ++i ) { - final LValue k = oldKeys[i]; - if ( k != null ) { - final Object v = oldValues[i]; - final int slot = hashFindSlot( k ); - hashKeys[slot] = k; - hashValues[slot] = v; - } - } - } -} diff --git a/src/core/org/luaj/vm/LThread.java b/src/core/org/luaj/vm/LThread.java deleted file mode 100644 index 4cdff1ce..00000000 --- a/src/core/org/luaj/vm/LThread.java +++ /dev/null @@ -1,182 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - - -/** - * Implementation of lua coroutines using Java Threads - */ -public class LThread extends LValue implements Runnable { - - private static final boolean USE_JAVA_THREADS = true; - - private static final int STATUS_SUSPENDED = 0; - private static final int STATUS_RUNNING = 1; - private static final int STATUS_NORMAL = 2; - private static final int STATUS_DEAD = 3; - private static final String[] NAMES = { - "suspended", - "running", - "normal", - "dead" }; - - private int status = STATUS_SUSPENDED; - - public final LuaState vm; - private Thread thread; - - static LThread running; - public LThread(LFunction c, LTable env) { - vm = new LuaState(env); - vm.pushlvalue(c); - } - - public int luaGetType() { - return Lua.LUA_TTHREAD; - } - - public String toJavaString() { - return "thread: "+hashCode(); - } - - // Set the environment if a thread, or closure, and return 1, otherwise return 0 - public boolean luaSetEnv(LTable t) { - vm._G = t; - return true; - } - - public String getStatus() { - return NAMES[status]; - } - - public static LThread getRunning() { - return running; - } - - public void run() { - synchronized ( this ) { - try { - vm.execute(); - } finally { - status = STATUS_DEAD; - this.notify(); - } - } - } - - public void yield() { - synchronized ( this ) { - if ( status != STATUS_RUNNING ) - vm.error(this+" not running"); - status = STATUS_SUSPENDED; - if ( USE_JAVA_THREADS ) { - this.notify(); - try { - this.wait(); - status = STATUS_RUNNING; - } catch ( InterruptedException e ) { - status = STATUS_DEAD; - vm.error(this+" "+e); - } - } - } - } - - // This needs to leave any values returned by yield in the coroutine - // on the calling vm stack - // @param vm - // @param nargs - // - public void resumeFrom(LuaState vm, int nargs) { - - synchronized ( this ) { - if ( status == STATUS_DEAD ) { - vm.resettop(); - vm.pushboolean(false); - vm.pushstring("cannot resume dead coroutine"); - return; - } - - // set prior thread to normal status while we are running - LThread prior = running; - try { - // set our status to running - if ( prior != null ) - prior.status = STATUS_NORMAL; - running = this; - status = STATUS_RUNNING; - - // copy args in - if (this.vm.cc < 0) { - vm.xmove(this.vm, nargs); - this.vm.prepStackCall(); - } else { - this.vm.resettop(); - vm.xmove(this.vm, nargs); - } - - // execute in the other thread - if ( USE_JAVA_THREADS ) { - // start the thread - if ( thread == null ) { - thread = new Thread(this); - thread.start(); - } - - // run this vm until it yields - this.notify(); - this.wait(); - } else { - // run this vm until it yields - while (this.vm.cc >= 0 && status == STATUS_RUNNING) - this.vm.exec(); - } - - // copy return values from yielding stack state - vm.resettop(); - if ( this.vm.cc >= 0 ) { - vm.pushboolean(status != STATUS_DEAD); - this.vm.xmove(vm, this.vm.gettop()); - } else { - vm.pushboolean(true); - this.vm.base = 0; - this.vm.xmove(vm, this.vm.gettop()); - } - - } catch ( Throwable t ) { - status = STATUS_DEAD; - vm.resettop(); - vm.pushboolean(false); - vm.pushstring("thread: "+t); - if ( USE_JAVA_THREADS ) { - this.notify(); - } - - } finally { - // previous thread is now running again - running = prior; - } - } - - } -} diff --git a/src/core/org/luaj/vm/LUserData.java b/src/core/org/luaj/vm/LUserData.java deleted file mode 100644 index 21ac2afc..00000000 --- a/src/core/org/luaj/vm/LUserData.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - - -public class LUserData extends LValue { - - public final Object m_instance; - public LTable m_metatable; - - public LUserData(Object obj) { - m_instance = obj; - } - - public LUserData(Object obj, LTable metatable) { - m_instance = obj; - m_metatable = metatable; - } - - public String toJavaString() { - return String.valueOf(m_instance); - } - - public boolean equals(Object obj) { - return (this == obj) || - (obj instanceof LUserData && this.m_instance == ((LUserData) obj).m_instance); - } - - public int hashCode() { - return System.identityHashCode( m_instance ); - } - - public int luaGetType() { - return Lua.LUA_TUSERDATA; - } - - public LTable luaGetMetatable() { - return m_metatable; - } - - public Object toJavaInstance() { - return m_instance; - } - - public boolean luaBinCmpUnknown( int opcode, LValue lhs ) { - if ( opcode == Lua.OP_EQ ) - return lhs.equals( this ); - return super.luaBinCmpUnknown( opcode, lhs ); - } - - public boolean isUserData() { - return true; - } -} diff --git a/src/core/org/luaj/vm/LValue.java b/src/core/org/luaj/vm/LValue.java deleted file mode 100644 index cfad9c8f..00000000 --- a/src/core/org/luaj/vm/LValue.java +++ /dev/null @@ -1,363 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - -import java.io.ByteArrayOutputStream; - - -abstract -public class LValue { - - /** Metatable tag for intercepting table gets */ - public static final LString TM_INDEX = new LString("__index"); - - /** Metatable tag for intercepting table sets */ - public static final LString TM_NEWINDEX = new LString("__newindex"); - - /** Metatable tag for intercepting table sets */ - public static final LString TM_METATABLE = new LString("__metatable"); - - /** Metatable tag for setting table mode */ - public static final LString TM_MODE = new LString("__mode"); - - private static final int MAXTAGLOOP = 100; - - protected void conversionError(String target) { - throw new LuaErrorException( "bad conversion: "+luaGetTypeName()+" to "+target ); - } - - private static LValue arithmeticError( Object type ) { - throw new LuaErrorException( "attempt to perform arithmetic on ? (a "+type+" value)" ); - } - - protected static LValue compareError( Object typea, Object typeb ) { - throw new LuaErrorException( "attempt to compare "+typea+" with "+typeb ); - } - - private LValue indexError(LuaState vm, LValue nontable) { - vm.error( "attempt to index ? (a "+nontable.luaGetTypeName()+" value)" ); - return LNil.NIL; - } - - public String id() { - return Integer.toHexString(hashCode()); - } - - /** Return true if this value can be represented as an "int" */ - public boolean isInteger() { - return false; - } - - /** Return true if this value is LNil.NIL, false otherwise */ - public boolean isNil() { - return false; - } - - // perform a lua call, return true if the call is to a lua function, false - // if it ran to completion. - public boolean luaStackCall(LuaState vm) { - vm.error("attempt to call "+this); - return false; - } - - // unsupported except for numbers - public LValue luaBinOpUnknown(int opcode, LValue lhs) { - return arithmeticError(luaGetTypeName()); - } - - // unsupported except for numbers - public LValue luaBinOpInteger(int opcode, int m_value) { - return arithmeticError(luaGetTypeName()); - } - - // unsupported except for numbers - public LValue luaBinOpDouble(int opcode, double m_value) { - return arithmeticError(luaGetTypeName()); - } - - // unsupported except for numbers, strings, and == with various combinations of Nil, Boolean, etc. - public boolean luaBinCmpUnknown(int opcode, LValue lhs) { - if ( opcode == Lua.OP_EQ ) - return lhs == this; - compareError(lhs.luaGetTypeName(), luaGetTypeName()); - return false; - } - - // unsupported except for strings - public boolean luaBinCmpString(int opcode, LString rhs) { - if ( opcode == Lua.OP_EQ ) - return false; - compareError(luaGetTypeName(), "string"); - return false; - } - - // unsupported except for numbers - public boolean luaBinCmpInteger(int opcode, int rhs) { - if ( opcode == Lua.OP_EQ ) - return false; - compareError(luaGetTypeName(), "number"); - return false; - } - - // unsupported except for numbers - public boolean luaBinCmpDouble(int opcode, double rhs) { - if ( opcode == Lua.OP_EQ ) - return false; - compareError(luaGetTypeName(), "number"); - return false; - } - - /** Dispatch a settable operation. - * Default method delegates back to the vm for metatable processing. - */ - public void luaSetTable(LuaState vm, LValue key, LValue val) { - vm.luaV_settable(this, key, val); - } - - - /** Dispatch a gettable operation. - * Default method delegates back to the vm for metatable processing. - */ - public LValue luaGetTable(LuaState vm, LValue key) { - return vm.luaV_gettable(this, key); - } - - /** Get the value as a LString - */ - public LString luaAsString() { - return new LString(toJavaString()); - } - - /** Override standard toString with lua String conversion by default */ - public String toString() { - return toJavaString(); - } - - /** Arithmetic negative */ - public LValue luaUnaryMinus() { - return arithmeticError(luaGetTypeName()); - } - - /** Built-in opcode LEN, for Strings and Tables */ - public int luaLength() { - throw new LuaErrorException( "attempt to get length of ? (a "+luaGetTypeName()+" value)" ); - } - - /** - * Valid for all types: get a metatable. Only tables and userdata can have a - * different metatable per instance, though, other types are restricted to - * one metatable per type. - * - * Since metatables on non-tables can only be set through Java and not Lua, - * this function should be overridden for each value type as necessary. - * - * @return null if there is no meta-table - */ - public LTable luaGetMetatable() { - return null; - } - - /** Valid for tables - * @param the new LTable, or null or LNil.NIL to reset the metatable to none - * @return this if unchanged, or new LTable if copied using weak table - */ - public LTable luaSetMetatable(LValue metatable) { - throw new LuaErrorException( "cannot set metatable for "+this.luaGetTypeName()); - } - - /** Valid for all types: return the int value identifying the type of this value */ - abstract public int luaGetType(); - - - /** Valid for all types: return the type of this value as an LString */ - public LString luaGetTypeName() { - return LString.LTYPENAMES[luaGetType()]; - } - - - /** Convert to a Java String */ - public String toJavaString() { - return null; - } - - /** Return value as a boolean */ - public boolean toJavaBoolean() { - return true; - } - - /** Return value as a byte */ - public byte toJavaByte() { - conversionError("number"); - return 0; - } - - /** Return value as a char */ - public char toJavaChar() { - conversionError("number"); - return 0; - } - - /** Return value as a double */ - public double toJavaDouble() { - conversionError("number"); - return 0; - } - - /** Return value as a float */ - public float toJavaFloat() { - conversionError("number"); - return 0; - } - - /** Return value as an integer */ - public int toJavaInt() { - conversionError("number"); - return 0; - } - - /** Return value as a long */ - public long toJavaLong() { - conversionError("number"); - return 0; - } - - /** Return value as a double */ - public short toJavaShort() { - conversionError("number"); - return 0; - } - - /** Convert to a Boolean value */ - public Boolean toJavaBoxedBoolean() { - conversionError("Boolean"); - return null; - } - - /** Convert to a Byte value */ - public Byte toJavaBoxedByte() { - conversionError("Byte"); - return null; - } - - /** Convert to a boxed Character value */ - public Character toJavaBoxedCharacter() { - conversionError("Character"); - return null; - } - - /** Convert to a boxed Double value */ - public Double toJavaBoxedDouble() { - conversionError("Double"); - return null; - } - - /** Convert to a boxed Float value */ - public Float toJavaBoxedFloat() { - conversionError("Float"); - return null; - } - - /** Convert to a boxed Integer value */ - public Integer toJavaBoxedInteger() { - conversionError("Integer"); - return null; - } - - /** Convert to a boxed Long value */ - public Long toJavaBoxedLong() { - conversionError("Long"); - return null; - } - - /** Convert to a boxed Short value */ - public Short toJavaBoxedShort() { - conversionError("Short"); - return null; - } - - /** Convert to a Java Object iff this is a LUserData value */ - public Object toJavaInstance() { - conversionError("instance"); - return null; - } - - /** Set the environment if a thread, or closure, and return true, otherwise return false */ - public boolean luaSetEnv(LTable t) { - return false; - } - - /** Get the environment of the object if it is a closure, or d if not a closure. - * @param d global environment to return if this is not a closure - */ - public LTable luaGetEnv(LTable d) { - return d; - } - - - /** Convert to a number if possible, or nil otherwise */ - public LValue luaToNumber() { - return LNil.NIL; - } - - /** Dereference a potentially weak reference, and return the value */ - public LValue toStrongReference() { - return this; - } - - /** Concatenate this value to a ByteArrayOutputStream */ - public void luaConcatTo(ByteArrayOutputStream baos) { - throw new LuaErrorException( "attempt to concatenate "+luaGetTypeName() ); - } - - /** Return true if this is a lua string, meaning it is - * either a LString or LNumber,since all numbers are - * convertible to strings in lua - */ - public boolean isString() { - return false; - } - - /** Return true if this is a LTable */ - public boolean isTable() { - return false; - } - - /** Return true if this is a LFunction */ - public boolean isFunction() { - return false; - } - - /** Returns true if this is an LUserData */ - public boolean isUserData() { - return false; - } - - /** Returns true if this is or can be made into a number */ - public boolean isNumber() { - return false; - } - - /** Returns true if this is a lua closure, false otherwise */ - public boolean isClosure() { - return false; - } -} diff --git a/src/core/org/luaj/vm/LWeakTable.java b/src/core/org/luaj/vm/LWeakTable.java deleted file mode 100644 index fccd6a84..00000000 --- a/src/core/org/luaj/vm/LWeakTable.java +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - -import java.lang.ref.WeakReference; - -import org.luaj.vm.LNil; -import org.luaj.vm.LValue; - -public class LWeakTable extends LTable { - - public LWeakTable() { - super(); - } - - public LWeakTable(int narray, int nhash) { - super(narray, nhash); - } - - public LWeakTable(LTable copy) { - super( copy.array.length, copy.hashKeys.length ); - for ( int i=0, k=1, n=copy.array.length; i> 52) & 0x7ffL) - 1023; - - if ( e >= 0 && e < 31 ) { - long f = bits & 0xFFFFFFFFFFFFFL; - int shift = 52 - e; - long intPrecMask = ( 1L << shift ) - 1; - if ( ( f & intPrecMask ) == 0 ) { - int intValue = (int)( f >> shift ) | ( 1 << e ); - return LInteger.valueOf( ( ( bits >> 63 ) != 0 ) ? -intValue : intValue ); - } - } - - double value = Double.longBitsToDouble(bits); - return LDouble.numberOf( value ); - } - - LNumber loadNumber() throws IOException { - if ( luacNumberFormat == DumpState.NUMBER_FORMAT_INTS_ONLY ) { - return LInteger.valueOf( loadInt() ); - } else { - return longBitsToLuaNumber( loadInt64() ); - } - } - - void loadConstants(LPrototype f) throws IOException { - int n = loadInt(); - LValue[] values = new LValue[n]; - for ( int i=0; i>1); /* `sBx' is signed */ - - public static final int MASK_OP = ((1<> POS_OP) & MAX_OP; - } - - public static int GETARG_A(int i) { - return (i >> POS_A) & MAXARG_A; - } - - public static int GETARG_B(int i) { - return (i >> POS_B) & MAXARG_B; - } - - public static int GETARG_C(int i) { - return (i >> POS_C) & MAXARG_C; - } - - public static int GETARG_Bx(int i) { - return (i >> POS_Bx) & MAXARG_Bx; - } - - public static int GETARG_sBx(int i) { - return ((i >> POS_Bx) & MAXARG_Bx) - MAXARG_sBx; - } - - - /* - ** Macros to operate RK indices - */ - - /** this bit 1 means constant (0 means register) */ - public static final int BITRK = (1 << (SIZE_B - 1)); - - /** test whether value is a constant */ - public static boolean ISK(int x) { - return 0 != ((x) & BITRK); - } - - /** gets the index of the constant */ - public static int INDEXK(int r) { - return ((int)(r) & ~BITRK); - } - - public static final int MAXINDEXRK = (BITRK - 1); - - /** code a constant index as a RK value */ - public static int RKASK(int x) { - return ((x) | BITRK); - } - - - /** - ** invalid register that fits in 8 bits - */ - public static final int NO_REG = MAXARG_A; - - - /* - ** R(x) - register - ** Kst(x) - constant (in constant table) - ** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x) - */ - - - /* - ** grep "ORDER OP" if you change these enums - */ - - /*---------------------------------------------------------------------- - name args description - ------------------------------------------------------------------------*/ - public static final int OP_MOVE = 0;/* A B R(A) := R(B) */ - public static final int OP_LOADK = 1;/* A Bx R(A) := Kst(Bx) */ - public static final int OP_LOADBOOL = 2;/* A B C R(A) := (Bool)B; if (C) pc++ */ - public static final int OP_LOADNIL = 3; /* A B R(A) := ... := R(B) := nil */ - public static final int OP_GETUPVAL = 4; /* A B R(A) := UpValue[B] */ - - public static final int OP_GETGLOBAL = 5; /* A Bx R(A) := Gbl[Kst(Bx)] */ - public static final int OP_GETTABLE = 6; /* A B C R(A) := R(B)[RK(C)] */ - - public static final int OP_SETGLOBAL = 7; /* A Bx Gbl[Kst(Bx)] := R(A) */ - public static final int OP_SETUPVAL = 8; /* A B UpValue[B] := R(A) */ - public static final int OP_SETTABLE = 9; /* A B C R(A)[RK(B)] := RK(C) */ - - public static final int OP_NEWTABLE = 10; /* A B C R(A) := {} (size = B,C) */ - - public static final int OP_SELF = 11; /* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */ - - public static final int OP_ADD = 12; /* A B C R(A) := RK(B) + RK(C) */ - public static final int OP_SUB = 13; /* A B C R(A) := RK(B) - RK(C) */ - public static final int OP_MUL = 14; /* A B C R(A) := RK(B) * RK(C) */ - public static final int OP_DIV = 15; /* A B C R(A) := RK(B) / RK(C) */ - public static final int OP_MOD = 16; /* A B C R(A) := RK(B) % RK(C) */ - public static final int OP_POW = 17; /* A B C R(A) := RK(B) ^ RK(C) */ - public static final int OP_UNM = 18; /* A B R(A) := -R(B) */ - public static final int OP_NOT = 19; /* A B R(A) := not R(B) */ - public static final int OP_LEN = 20; /* A B R(A) := length of R(B) */ - - public static final int OP_CONCAT = 21; /* A B C R(A) := R(B).. ... ..R(C) */ - - public static final int OP_JMP = 22; /* sBx pc+=sBx */ - - public static final int OP_EQ = 23; /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ - public static final int OP_LT = 24; /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ - public static final int OP_LE = 25; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ - - public static final int OP_TEST = 26; /* A C if not (R(A) <=> C) then pc++ */ - public static final int OP_TESTSET = 27; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ - - public static final int OP_CALL = 28; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ - public static final int OP_TAILCALL = 29; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ - public static final int OP_RETURN = 30; /* A B return R(A), ... ,R(A+B-2) (see note) */ - - public static final int OP_FORLOOP = 31; /* A sBx R(A)+=R(A+2); - if R(A) =) R(A)*/ - public static final int OP_CLOSURE = 36; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ - - public static final int OP_VARARG = 37; /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ - - - public static final int NUM_OPCODES = OP_VARARG + 1; - - - - /*=========================================================================== - Notes: - (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, - and can be 0: OP_CALL then sets `top' to last_result+1, so - next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. - - (*) In OP_VARARG, if (B == 0) then use actual number of varargs and - set top (like in OP_CALL with C == 0). - - (*) In OP_RETURN, if (B == 0) then return up to `top' - - (*) In OP_SETLIST, if (B == 0) then B = `top'; - if (C == 0) then next `instruction' is real C - - (*) For comparisons, A specifies what condition the test should accept - (true or false). - - (*) All `skips' (pc++) assume that next instruction is a jump - ===========================================================================*/ - - - /* - ** masks for instruction properties. The format is: - ** bits 0-1: op mode - ** bits 2-3: C arg mode - ** bits 4-5: B arg mode - ** bit 6: instruction set register A - ** bit 7: operator is a test - */ - - public static final int OpArgN = 0; /* argument is not used */ - public static final int OpArgU = 1; /* argument is used */ - public static final int OpArgR = 2; /* argument is a register or a jump offset */ - public static final int OpArgK = 3; /* argument is a constant or register/constant */ - - public static final int[] luaP_opmodes = { - /* T A B C mode opcode */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_MOVE */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx), /* OP_LOADK */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_LOADBOOL */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_LOADNIL */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_GETUPVAL */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx), /* OP_GETGLOBAL */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgK<<2) | (iABC), /* OP_GETTABLE */ - (0<<7) | (0<<6) | (OpArgK<<4) | (OpArgN<<2) | (iABx), /* OP_SETGLOBAL */ - (0<<7) | (0<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_SETUPVAL */ - (0<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SETTABLE */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_NEWTABLE */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgK<<2) | (iABC), /* OP_SELF */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_ADD */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SUB */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MUL */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_DIV */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MOD */ - (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_POW */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_UNM */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_NOT */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_LEN */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgR<<2) | (iABC), /* OP_CONCAT */ - (0<<7) | (0<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx), /* OP_JMP */ - (1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_EQ */ - (1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_LT */ - (1<<7) | (0<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_LE */ - (1<<7) | (1<<6) | (OpArgR<<4) | (OpArgU<<2) | (iABC), /* OP_TEST */ - (1<<7) | (1<<6) | (OpArgR<<4) | (OpArgU<<2) | (iABC), /* OP_TESTSET */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_CALL */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_TAILCALL */ - (0<<7) | (0<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_RETURN */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx), /* OP_FORLOOP */ - (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iAsBx), /* OP_FORPREP */ - (1<<7) | (0<<6) | (OpArgN<<4) | (OpArgU<<2) | (iABC), /* OP_TFORLOOP */ - (0<<7) | (0<<6) | (OpArgU<<4) | (OpArgU<<2) | (iABC), /* OP_SETLIST */ - (0<<7) | (0<<6) | (OpArgN<<4) | (OpArgN<<2) | (iABC), /* OP_CLOSE */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABx), /* OP_CLOSURE */ - (0<<7) | (1<<6) | (OpArgU<<4) | (OpArgN<<2) | (iABC), /* OP_VARARG */ - }; - - public static int getOpMode(int m) { - return luaP_opmodes[m] & 3; - } - public static int getBMode(int m) { - return (luaP_opmodes[m] >> 4) & 3; - } - public static int getCMode(int m) { - return (luaP_opmodes[m] >> 2) & 3; - } - public static boolean testAMode(int m) { - return 0 != (luaP_opmodes[m] & (1 << 6)); - } - public static boolean testTMode(int m) { - return 0 != (luaP_opmodes[m] & (1 << 7)); - } - - /* number of list items to accumulate before a SETLIST instruction */ - public static final int LFIELDS_PER_FLUSH = 50; - - // type constants - - public static final int LUA_TINT = (-2); - public static final int LUA_TNONE = (-1); - public static final int LUA_TNIL = 0; - public static final int LUA_TBOOLEAN = 1; - public static final int LUA_TLIGHTUSERDATA = 2; - public static final int LUA_TNUMBER = 3; - public static final int LUA_TSTRING = 4; - public static final int LUA_TTABLE = 5; - public static final int LUA_TFUNCTION = 6; - public static final int LUA_TUSERDATA = 7; - public static final int LUA_TTHREAD = 8; - public static final int LUA_TVALUE = 9; - - public static final String[] TYPE_NAMES = { - "nil", - "boolean", - "lightuserdata", - "number", - "string", - "table", - "function", - "userdata", - "thread", - "value", - }; - -} diff --git a/src/core/org/luaj/vm/LuaErrorException.java b/src/core/org/luaj/vm/LuaErrorException.java deleted file mode 100644 index a0e8d041..00000000 --- a/src/core/org/luaj/vm/LuaErrorException.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - -/** - * RuntimeException that is thrown and caught in response to a lua error. - * This error does not indicate any problem with the normal functioning - * of the Lua VM, but rather indicates that the lua script being interpreted - * has encountered a lua error, eigher via LuaState.error() or lua error() calls. - * - */ -public class LuaErrorException extends RuntimeException { - - private static final String DEFAULT_MESSAGE = "lua error"; - - /** - * Construct a LuaErrorException with the default message. - */ - public LuaErrorException() { - this(DEFAULT_MESSAGE); - } - - /** - * Construct a LuaErrorException in response to a Throwable that was caught - * and with the default message. - */ - public LuaErrorException(Throwable cause) { - this(DEFAULT_MESSAGE+": "+cause); - } - - /** - * Construct a LuaErrorException with a specific message. - * - * @param message message to supply - */ - public LuaErrorException(String message) { - this(null, message, -1); - } - - /** - * Construct the message around a specific vm and with a particular level of debug info - * @param vm - * @param message - * @param level 0 for no message, >=1 for current call or above, -1 for most recent lua call - */ - public LuaErrorException(LuaState vm, String message, int level) { - super( addLineInfo( vm, message, level ) ); - } - - /** - * Append line info as per level - * @param vm - * @param message - * @param level - * @return - */ - private static String addLineInfo(LuaState vm, String message, int level) { - // add position information - if ( vm == null ) { - if ( LThread.running != null ) - vm = LThread.running.vm; - else - vm = LuaState.mainState; - if ( vm == null ) - return message; - } - if ( level > 0 ) { - message = vm.getFileLine(level); - } - return vm.luaV_call_errfunc( message ); - } -} diff --git a/src/core/org/luaj/vm/LuaState.java b/src/core/org/luaj/vm/LuaState.java deleted file mode 100644 index 1504dee0..00000000 --- a/src/core/org/luaj/vm/LuaState.java +++ /dev/null @@ -1,2553 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.vm; - -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.util.Stack; - -import org.luaj.lib.BaseLib; -import org.luaj.lib.CoroutineLib; -import org.luaj.lib.MathLib; -import org.luaj.lib.PackageLib; -import org.luaj.lib.StringLib; -import org.luaj.lib.TableLib; - -/** - *
- *

LuaState

- * - *
- * typedef struct LuaState;
- * 
- * - *

- * Opaque structure that keeps the whole state of a Lua interpreter. The Lua - * library is fully reentrant: it has no global variables. All information about - * a state is kept in this structure. - * - * - *

- * Here we list all functions and types from the C API in alphabetical - * order. Each function has an indicator like this: [-o, +p, - * x] - * - *

- * The first field, o, is how many elements the function pops - * from the stack. The second field, p, is how many elements the - * function pushes onto the stack. (Any function always pushes its results after - * popping its arguments.) A field in the form x|y means the - * function may push (or pop) x or y elements, - * depending on the situation; an interrogation mark '?' means - * that we cannot know how many elements the function pops/pushes by looking - * only at its arguments (e.g., they may depend on what is on the stack). The - * third field, x, tells whether the function may throw errors: '-' - * means the function never throws any error; 'm' means the - * function may throw an error only due to not enough memory; 'e' - * means the function may throw other kinds of errors; 'v' - * means the function may throw an error on purpose. - * - * - */ -public class LuaState extends Lua { - - /* thread status; 0 is OK */ - public static final int LUA_YIELD = 1; - public static final int LUA_ERRRUN = 2; - public static final int LUA_ERRSYNTAX = 3; - public static final int LUA_ERRMEM = 4; - public static final int LUA_ERRERR = 5; - - private static final int LUA_MINSTACK = 20; - private static final int LUA_MINCALLS = 10; - private static final int MAXTAGLOOP = 100; - - // hook function values - private static final int LUA_HOOKCALL = 0; - private static final int LUA_HOOKRET = 1; - private static final int LUA_HOOKLINE = 2; - private static final int LUA_HOOKCOUNT = 3; - private static final int LUA_HOOKTAILRET = 4; - public static final int LUA_MASKCALL = (1 << LUA_HOOKCALL); - public static final int LUA_MASKRET = (1 << LUA_HOOKRET); - public static final int LUA_MASKLINE = (1 << LUA_HOOKLINE); - - public int base = 0; - public int top = 0; - protected int nresults = -1; - public LValue[] stack = new LValue[LUA_MINSTACK]; - public int cc = -1; - public CallInfo[] calls = new CallInfo[LUA_MINCALLS]; - protected Stack upvals = new Stack(); - protected LValue errfunc; - - static LuaState mainState; - public LTable _G; - - // debug hooks - these MUST NOT be initialized, - // so that a later obfuscation step can decide to remove them. - private boolean hooksenabled,inhook; - private int hookmask; - private int hookcount; - private LFunction hookfunc; - private int hookincr; - private int hookline,hookcc; - - protected void debugHooks(int pc) {} - protected void debugAssert(boolean b) {} - - // ------------------- constructors --------------------- - /** - * Creates a new, independent LuaState instance. [-0, +0, - * -] - * - *

- * Returns NULL if cannot create the state (due to lack of - * memory). The argument f is the allocator function; Lua - * does all memory allocation for this state through this function. The - * second argument, ud, is an opaque pointer that Lua simply - * passes to the allocator in every call. - */ - protected LuaState() { - _G = new LTable(); - mainState = this; - } - - /** - * Create a LuaState with a specific global environment. Used by LThread. - * - * @param globals the LTable to use as globals for this LuaState - */ - LuaState(LTable globals) { - _G = globals; - } - - /** - * Performs the initialization. - */ - public void init() {} - - /** - * Perform any shutdown/clean up tasks if needed - */ - public void shutdown() {} - - /** - * Install the standard set of libraries used by most implementations: - * BaseLib, CoroutineLib, MathLib, PackageLib, TableLib, StringLib - */ - public void installStandardLibs() { - PackageLib.install(_G); - BaseLib.install(_G); - CoroutineLib.install(_G); - MathLib.install(_G); - TableLib.install(_G); - StringLib.install(_G); - } - - // ================ interfaces for performing calls - - /** - * Create a call frame for a call that has been set up on - * the stack. The first value on the stack must be a Closure, - * and subsequent values are arguments to the closure. - */ - public void prepStackCall() { - LClosure c = (LClosure) stack[base]; - int resultbase = base; - // Expand the stack if necessary - checkstack( c.p.maxstacksize ); - if ( c.p.is_vararg == 0 ) { - base += 1; - luaV_adjusttop( base+c.p.numparams ); - } else { - /* vararg function */ - int npar = c.p.numparams; - int narg = Math.max(0, top - base - 1); - int nfix = Math.min(narg, npar); - int nvar = Math.max(0, narg-nfix); - - - // must copy args into position, add number parameter - stack[top] = LInteger.valueOf(nvar); - System.arraycopy(stack, base+1, stack, top+1, nfix); - base = top + 1; - top = base + nfix; - luaV_adjusttop( base + npar ); - - // add 'arg' compatibility variable - if ( (c.p.is_vararg & VARARG_NEEDSARG) != 0 ) { - LTable arg = new LTable(nvar,1); - for ( int i=1,j=base-nvar-1; i<=nvar; i++, j++ ) - arg.put(i, stack[j]); - arg.put("n", nvar); - pushlvalue( arg ); - } - } - final int newcc = cc + 1; - if ( newcc >= calls.length ) { - CallInfo[] newcalls = new CallInfo[ calls.length * 2 ]; - System.arraycopy( calls, 0, newcalls, 0, cc+1 ); - calls = newcalls; - } - calls[newcc] = new CallInfo(c, base, top, resultbase, nresults); - cc = newcc; - - stackClear( top, base + c.p.maxstacksize ); - } - - /** - * Execute bytecodes until the current call completes - * or the vm yields. - */ - public void execute() { - for ( int cb=cc; cc>=cb; ) - exec(); - } - - /** - * Put the closure on the stack with arguments, - * then perform the call. Leave return values - * on the stack for later querying. - * - * @param c - * @param values - */ - public void doCall( LClosure c, LValue[] args ) { - settop(0); - pushlvalue( c ); - for ( int i=0, n=(args!=null? args.length: 0); i=0? calls[cc].base: 0); - } - - /** - * Invoke a LFunction being called via prepStackCall() - * @param javaFunction - */ - public void invokeJavaFunction(LFunction javaFunction) { - ++base; - - // call hook - if ( hooksenabled && !inhook ) { - debugCallHooks( ); - } - - int nactual = javaFunction.invoke(this); - - // call hook - if ( hooksenabled && !inhook ) { - debugReturnHooks( ); - } - - - if (nactual < 0) - nactual = top - base; - System.arraycopy(stack, top-nactual, stack, --base, nactual); - luaV_settop_fillabove( base+nactual ); - } - - // ================== error processing ================= - - /** - * Calls a function. [-(nargs + 1), +nresults, e] - * - * - *

- * To call a function you must use the following protocol: first, the - * function to be called is pushed onto the stack; then, the arguments to - * the function are pushed in direct order; that is, the first argument is - * pushed first. Finally you call lua_call; - * nargs is the number of arguments that you pushed onto the - * stack. All arguments and the function value are popped from the stack - * when the function is called. The function results are pushed onto the - * stack when the function returns. The number of results is adjusted to - * nresults, unless nresults is LUA_MULTRET. In this case, - * all results from the function are pushed. Lua takes care that - * the returned values fit into the stack space. The function results are - * pushed onto the stack in direct order (the first result is pushed first), - * so that after the call the last result is on the top of the stack. - * - * - *

- * Any error inside the called function is propagated upwards (with a - * longjmp). - * - * - *

- * The following example shows how the host program may do the equivalent to - * this Lua code: - * - *

-	 * a = f("how", t.x, 14)
-	 * 
- * - *

- * Here it is in C: - * - *

-	 * lua_getfield(L, LUA_GLOBALSINDEX, "f"); // function to be called 
-	 * lua_pushstring(L, "how"); // 1st argument 
-	 * lua_getfield(L, LUA_GLOBALSINDEX, "t"); // table to be indexed 
-	 * lua_getfield(L, -1, "x"); // push result of t.x (2nd arg) 
-	 * lua_remove(L, -2); // remove 't' from the stack 
-	 * lua_pushinteger(L, 14); // 3rd argument 
-	 * lua_call(L, 3, 1); // call 'f' with 3 arguments and 1 result 
-	 * lua_setfield(L, LUA_GLOBALSINDEX, "a"); // set global 'a' 
-	 * 
- * - *

- * Note that the code above is "balanced": at its end, the stack is back to - * its original configuration. This is considered good programming practice. - */ - public void call( int nargs, int nreturns ) { - - // save stack state - int oldbase = base; - int oldcc = cc; - try { - - // rb is base of new call frame - int rb = this.base = top - 1 - nargs; - - // make or set up the call - this.nresults = nreturns; - - if (this.stack[base].luaStackCall(this)) { - - // call hook - if ( hooksenabled && ! inhook ) { - debugCallHooks( ); - } - - // call was set up on the stack, - // we still have to execute it - execute(); - } - - // adjustTop only for case when call was completed - // and number of args > 0. If call completed but - // c == 0, leave top to point to end of results - if (nreturns >= 0) - luaV_adjusttop(rb + nreturns); - - } finally { - this.base = oldbase; - this.cc = oldcc; - } - } - - /** - * Calls a function in protected mode. [-(nargs + 1), - * +(nresults|1), -] - * - * - *

- * Both nargs and nresults have the same - * meaning as in lua_call. If there - * are no errors during the call, lua_pcall - * behaves exactly like lua_call. - * However, if there is any error, lua_pcall - * catches it, pushes a single value on the stack (the error message), and - * returns an error code. Like lua_call, - * lua_pcall always removes the - * function and its arguments from the stack. - * - *

- * The lua_pcall function returns - * 0 in case of success or one of the following error codes (defined in - * lua.h): - * - *

    - * - *
  • LUA_ERRRUN: a - * runtime error.
  • - * - *
  • LUA_ERRMEM: - * memory allocation error. For such errors, Lua does not call the error - * handler function.
  • - * - *
  • LUA_ERRERR: - * error while running the error handler function.
  • - * - *
- */ - public int pcall( int nargs, int nreturns ) { - // save stack state - int oldtop = top; - int oldbase = base; - int oldcc = cc; - try { - // rb is base of new call frame - int rb = this.base = top - 1 - nargs; - - // make or set up the call - this.nresults = nreturns; - if (this.stack[base].luaStackCall(this)) { - - // call hook - if ( hooksenabled ) { - debugCallHooks( ); - } - - // call was set up on the stack, - // we still have to execute it - execute(); - } - - // adjustTop only for case when call was completed - // and number of args > 0. If call completed but - // c == 0, leave top to point to end of results - if (nreturns >= 0) - luaV_adjusttop(rb + nreturns); - - // restore base - this.base = oldbase; - - return 0; - } catch ( Throwable t ) { - this.base = oldbase; - this.cc = oldcc; - closeUpVals(oldtop); /* close eventual pending closures */ - String s = t.getMessage(); - resettop(); - if ( s != null ) - pushstring( s ); - else - pushnil(); - return (t instanceof OutOfMemoryError? LUA_ERRMEM: LUA_ERRRUN); - } - } - - - /** - * Calls a function in protected mode with an error function. - * [-(nargs + 1), +(nresults|1), -] - * - * - *

- * Both nargs and nresults have the same - * meaning as in lua_call. If there - * are no errors during the call, lua_xpcall - * behaves exactly like lua_call. - * However, if there is any error, lua_xpcall - * catches it, pushes a single value on the stack (the error message), and - * tries to call the supplied error function. - * - *

In case of runtime errors, this function - * will be called with the error message and its return value will be the - * message returned on the stack by lua_pcall. - * - *

- * Typically, the error handler function is used to add more debug - * information to the error message, such as a stack traceback. Such - * information cannot be gathered after the return of lua_pcall, - * since by then the stack has unwound. - * - *

- * The return values for - * lua_xpcall are the same as those for - * lua_pcall - */ - public int xpcall( int nargs, int nreturns, LValue errfunc ) { - LValue preverrfunc = this.errfunc; - try { - this.errfunc = errfunc; - return pcall( nargs, nreturns ); - } finally { - this.errfunc = preverrfunc; - } - } - - /** - * Loads a Lua chunk. [-0, +1, -] - * - *

- * If there are no errors, lua_load - * pushes the compiled chunk as a Lua function on top of the stack. - * Otherwise, it pushes an error message. The return values of lua_load are: - * - *

    - * - *
  • 0: no errors;
  • - * - *
  • LUA_ERRSYNTAX: - * syntax error during pre-compilation;
  • - * - *
  • LUA_ERRMEM: - * memory allocation error.
  • - * - *
- * - *

- * This function only loads a chunk; it does not run it. - * - * - *

- * lua_load automatically detects - * whether the chunk is text or binary, and loads it accordingly (see - * program luac). - * - * - *

- * The lua_load function uses a - * user-supplied reader function to read the chunk (see lua_Reader). The - * data argument is an opaque value passed to the reader - * function. - * - * - *

- * The chunkname argument gives a name to the chunk, which is - * used for error messages and in debug information (see §3.8). - */ - public int load( InputStream is, String chunkname ) { - try { - LPrototype p = LoadState.undump(this, is, chunkname ); - pushlvalue( p.newClosure( _G ) ); - return 0; - } catch ( Throwable t ) { - pushstring( t.getMessage() ); - return (t instanceof OutOfMemoryError? LUA_ERRMEM: LUA_ERRSYNTAX); - } - } - - // ================ execute instructions - private LValue RKBC(LValue[] k, int bc) { - return LuaState.ISK(bc) ? - k[LuaState.INDEXK(bc)]: - stack[base + bc]; - } - - private LValue GETARG_RKB(LValue[] k, int i) { - return RKBC(k, GETARG_B(i)); - } - - private LValue GETARG_RKC(LValue[] k, int i) { - return RKBC(k, GETARG_C(i)); - } - - private final void stackClear(int startIndex, int endIndex) { - for (; startIndex < endIndex; startIndex++) { - stack[startIndex] = LNil.NIL; - } - } - - /** execute instructions up to a yield, return, or call */ - public void exec() { - if ( cc < 0 ) - return; - - int i, a, b, c, o, n, cb; - LValue rkb, rkc, nvarargs, key, val; - LValue i0, step, idx, limit, init, table; - boolean back, body; - LPrototype proto; - LClosure newClosure; - - // reload values from the current call frame - // into local variables - CallInfo ci = calls[cc]; - LClosure cl = ci.closure; - LPrototype p = cl.p; - int[] code = p.code; - LValue[] k = p.k; - - this.base = ci.base; - - // loop until a return instruction is processed, - // or the vm yields - while (true) { - debugAssert( ci == calls[cc] ); - - // sync up top - ci.top = top; - - // allow debug hooks a chance to operate - debugHooks( ci.pc ); - if ( hooksenabled && ! inhook ) { - //Print.printState(this, base, top, base+cl.p.maxstacksize, cl, ci.pc); - debugBytecodeHooks( ci.pc ); - } - - // advance program counter - i = code[ci.pc++]; - - // get opcode and first arg - o = (i >> POS_OP) & MAX_OP; - a = (i >> POS_A) & MAXARG_A; - - switch (o) { - case LuaState.OP_MOVE: { - b = LuaState.GETARG_B(i); - this.stack[base + a] = this.stack[base + b]; - continue; - } - case LuaState.OP_LOADK: { - b = LuaState.GETARG_Bx(i); - this.stack[base + a] = k[b]; - continue; - } - case LuaState.OP_LOADBOOL: { - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - this.stack[base + a] = (b != 0 ? LBoolean.TRUE : LBoolean.FALSE); - if (c != 0) - ci.pc++; /* skip next instruction (if C) */ - continue; - } - case LuaState.OP_LOADNIL: { - b = LuaState.GETARG_B(i); - do { - this.stack[base + b] = LNil.NIL; - } while ((--b) >= a); - continue; - } - case LuaState.OP_GETUPVAL: { - b = LuaState.GETARG_B(i); - this.stack[base + a] = cl.upVals[b].getValue(); - continue; - } - case LuaState.OP_GETGLOBAL: { - b = LuaState.GETARG_Bx(i); - key = k[b]; - table = cl.env; - val = this.luaV_gettable(table, key); - this.stack[base + a] = val; - continue; - } - case LuaState.OP_GETTABLE: { - b = LuaState.GETARG_B(i); - key = GETARG_RKC(k, i); - table = this.stack[base + b]; - val = this.luaV_gettable(table, key); - this.stack[base + a] = val; - continue; - } - case LuaState.OP_SETGLOBAL: { - b = LuaState.GETARG_Bx(i); - key = k[b]; - val = this.stack[base + a]; - table = cl.env; - this.luaV_settable(table, key, val); - continue; - } - case LuaState.OP_SETUPVAL: { - b = LuaState.GETARG_B(i); - cl.upVals[b].setValue( this.stack[base + a] ); - continue; - } - case LuaState.OP_SETTABLE: { - key = GETARG_RKB(k, i); - val = GETARG_RKC(k, i); - table = this.stack[base + a]; - this.luaV_settable(table, key, val); - continue; - } - case LuaState.OP_NEWTABLE: { - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - this.stack[base + a] = new LTable(b, c); - continue; - } - case LuaState.OP_SELF: { - rkb = stack[base + GETARG_B(i)]; - rkc = GETARG_RKC(k, i); - val = this.luaV_gettable(rkb, rkc); - this.stack[base + a] = val; - this.stack[base + a + 1] = rkb; - continue; - } - case LuaState.OP_ADD: - case LuaState.OP_SUB: - case LuaState.OP_MUL: - case LuaState.OP_DIV: - case LuaState.OP_MOD: - case LuaState.OP_POW: { - rkb = GETARG_RKB(k, i); - rkc = GETARG_RKC(k, i); - this.stack[base + a] = rkc.luaBinOpUnknown(o, rkb); - continue; - } - case LuaState.OP_UNM: { - rkb = GETARG_RKB(k, i); - this.stack[base + a] = rkb.luaUnaryMinus(); - continue; - } - case LuaState.OP_NOT: { - rkb = GETARG_RKB(k, i); - this.stack[base + a] = (!rkb.toJavaBoolean() ? LBoolean.TRUE - : LBoolean.FALSE); - continue; - } - case LuaState.OP_LEN: { - rkb = GETARG_RKB(k, i); - this.stack[base + a] = LInteger.valueOf( rkb.luaLength() ); - continue; - } - case LuaState.OP_CONCAT: { - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - int numValues = c - b + 1; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - for (int j = b, l = 0; j <= c; j++, l++) { - this.stack[base + j].luaConcatTo( baos ); - } - this.stack[base + a] = new LString( baos.toByteArray() ); - continue; - } - case LuaState.OP_JMP: { - ci.pc += LuaState.GETARG_sBx(i); - continue; - } - case LuaState.OP_EQ: - case LuaState.OP_LT: - case LuaState.OP_LE: { - rkb = GETARG_RKB(k, i); - rkc = GETARG_RKC(k, i); - boolean test = rkc.luaBinCmpUnknown(o, rkb); - if (test == (a == 0)) - ci.pc++; - continue; - } - case LuaState.OP_TEST: { - c = LuaState.GETARG_C(i); - if (this.stack[base + a].toJavaBoolean() != (c != 0)) - ci.pc++; - continue; - } - case LuaState.OP_TESTSET: { - rkb = stack[base + GETARG_B(i)]; - c = LuaState.GETARG_C(i); - if (rkb.toJavaBoolean() != (c != 0)) - ci.pc++; - else - this.stack[base + a] = rkb; - continue; - } - case LuaState.OP_CALL: { - - // ra is base of new call frame - this.base += a; - - // number of args - b = LuaState.GETARG_B(i); - if (b != 0) // else use previous instruction set top - luaV_settop_fillabove( base + b ); - - // number of return values we need - c = LuaState.GETARG_C(i); - - // make or set up the call - this.nresults = c - 1; - if (this.stack[base].luaStackCall(this)) { - - // call hook - if ( hooksenabled && ! inhook ) { - debugCallHooks( ); - } - - return; - } - - // adjustTop only for case when call was completed - // and number of args > 0. If call completed but - // c == 0, leave top to point to end of results - if (c > 0) - luaV_adjusttop(base + c - 1); - - // restore base - base = ci.base; - - continue; - } - - case LuaState.OP_TAILCALL: { - // return hook - if ( hooksenabled && ! inhook ) { - debugTailReturnHooks( ); - } - - // close up values - closeUpVals(base); - - // copy down the frame before calling! - - // number of args (including the function) - b = LuaState.GETARG_B(i); - if (b != 0) // else use previous instruction set top - luaV_settop_fillabove( base + a + b ); - else - b = top - (base + a); - - // copy call + all args, discard current frame - System.arraycopy(stack, base + a, stack, ci.resultbase, b); - this.base = ci.resultbase; - luaV_settop_fillabove( base + b ); - this.nresults = ci.nresults; - --cc; - - // make or set up the call - try { - if (this.stack[base].luaStackCall(this)) { - - // call hook - if ( hooksenabled && ! inhook ) { - debugCallHooks( ); - } - - return; - } - } catch (LuaErrorException e) { - // in case of lua error, we need to restore cc so that - // the debug can get the correct location where the error - // occured. - cc++; - throw e; - } - - // adjustTop only for case when call was completed - // and number of args > 0. If call completed but - // c == 0, leave top to point to end of results - if (ci.nresults >= 0) - luaV_adjusttop(base + ci.nresults); - - // force restore of base, etc. - return; - } - - case LuaState.OP_RETURN: { - // return hook - if ( hooksenabled && ! inhook ) { - debugReturnHooks( ); - } - - // close up values - closeUpVals( base ); - - // number of return vals to return - b = LuaState.GETARG_B(i) - 1; - if (b >= 0) // else use previous instruction set top - luaV_settop_fillabove( base + a + b ); - else - b = top - (base + a); - - // number to copy down - System.arraycopy(stack, base + a, stack, ci.resultbase, b); - debugAssert( ci.resultbase + b <= top ); - luaV_settop_fillabove( ci.resultbase + b ); - - // adjust results to what caller expected - if (ci.nresults >= 0) - luaV_adjusttop(ci.resultbase + ci.nresults); - - // pop the call stack - calls[cc--] = null; - - // force a reload of the calling context - return; - } - case LuaState.OP_FORLOOP: { - i0 = this.stack[base + a]; - step = this.stack[base + a + 2]; - idx = step.luaBinOpUnknown(Lua.OP_ADD, i0); - limit = this.stack[base + a + 1]; - back = step.luaBinCmpInteger(Lua.OP_LT, 0); - body = (back ? idx.luaBinCmpUnknown(Lua.OP_LE, limit) : limit - .luaBinCmpUnknown(Lua.OP_LE, idx)); - if (body) { - this.stack[base + a] = idx; - this.stack[base + a + 3] = idx; - ci.pc += LuaState.GETARG_sBx(i); - } - continue; - } - case LuaState.OP_FORPREP: { - init = this.stack[base + a].luaToNumber(); - limit = this.stack[base + a + 1].luaToNumber(); - step = this.stack[base + a + 2].luaToNumber(); - if ( init.isNil() ) error("'for' initial value must be a number"); - if ( limit.isNil() ) error("'for' limit must be a number"); - if ( step.isNil() ) error("'for' step must be a number"); - this.stack[base + a] = step.luaBinOpUnknown(Lua.OP_SUB, init); - this.stack[base + a + 1] = limit; - this.stack[base + a + 2] = step; - b = LuaState.GETARG_sBx(i); - ci.pc += b; - continue; - } - case LuaState.OP_TFORLOOP: { - cb = base + a + 3; /* call base */ - base = cb; - System.arraycopy(this.stack, cb-3, this.stack, cb, 3); - luaV_settop_fillabove( cb + 3 ); - - // call the iterator - c = LuaState.GETARG_C(i); - this.nresults = c; - if (this.stack[cb].luaStackCall(this)) - execute(); - base = ci.base; - luaV_adjusttop( cb + c ); - - // test for continuation - if (!this.stack[cb].isNil() ) { // continue? - this.stack[cb-1] = this.stack[cb]; // save control variable - } else { - ci.pc++; // skip over jump - } - continue; - } - case LuaState.OP_SETLIST: { - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - int listBase = base + a; - if (b == 0) { - b = top - listBase - 1; - } - if (c == 0) { - c = code[ci.pc++]; - } - int offset = (c-1) * LFIELDS_PER_FLUSH; - LTable tbl = (LTable) this.stack[base + a]; - tbl.arrayPresize( offset + b ); - for (int j=1; j<=b; j++) { - tbl.put(offset+j, stack[listBase + j]); - } - continue; - } - case LuaState.OP_CLOSE: { - closeUpVals( base + a ); // close upvals higher in the stack than position a - continue; - } - case LuaState.OP_CLOSURE: { - b = LuaState.GETARG_Bx(i); - proto = cl.p.p[b]; - newClosure = proto.newClosure(cl.env); - for (int j = 0; j < newClosure.upVals.length; j++, ci.pc++) { - i = code[ci.pc]; - o = LuaState.GET_OPCODE(i); - b = LuaState.GETARG_B(i); - if (o == LuaState.OP_GETUPVAL) { - newClosure.upVals[j] = cl.upVals[b]; - } else if (o == LuaState.OP_MOVE) { - newClosure.upVals[j] = findUpVal( base + b ); - } else { - throw new java.lang.IllegalArgumentException( - "bad opcode: " + o); - } - } - this.stack[base + a] = newClosure; - continue; - } - case LuaState.OP_VARARG: { - // figure out how many args to copy - b = LuaState.GETARG_B(i) - 1; - nvarargs = this.stack[base - 1]; - n = nvarargs.toJavaInt(); - if (b == LuaState.LUA_MULTRET) { - b = n; // use entire varargs supplied - luaV_settop_fillabove( base + a + b ); - } - - // copy args up to call stack area - checkstack(a+b); - for (int j = 0; j < b; j++) - this.stack[base + a + j] = (j < n ? - this.stack[base - n + j - 1] - : LNil.NIL); - continue; - } - } - } - } - - public UpVal findUpVal( int target ) { - UpVal up; - int i; - for ( i = this.upvals.size() - 1; i >= 0; --i ) { - up = (UpVal) this.upvals.elementAt( i ); - if ( up.state == this && up.position == target ) { - return up; - } else if ( up.position < target ) { - break; - } - } - - up = new UpVal( this, target ); - this.upvals.insertElementAt( up, i + 1 ); - return up; - } - - public void closeUpVals( int limit ) { - while ( !upvals.empty() && ( (UpVal) this.upvals.lastElement() ).close( limit ) ) { - this.upvals.pop(); - } - } - - public CallInfo getStackFrame(int callStackDepth) { - return calls[cc-callStackDepth]; - } - - private void indexError(LValue nontable) { - error( "attempt to index ? (a "+nontable.luaGetTypeName()+" value)" ); - } - - public static LValue luaV_getmetafield(LValue t, LString tag) { - LTable mt = t.luaGetMetatable(); - if ( mt == null ) - return null; - LValue h = mt.get(tag); - return h.isNil()? null: h; - } - - /** Get a key from a table using full metatable processing */ - public LValue luaV_gettable(LValue table, LValue key) { - LValue h=LNil.NIL,t=table; - for ( int loop=0; loop newTop) - this.stack[--top] = LNil.NIL; - } - - /** Move top down, filling from above */ - private void luaV_settop_fillabove(int newTop) { - while (top > newTop) - this.stack[--top] = LNil.NIL; - top = newTop; - } - - - //=============================================================== - // Lua Java API - //=============================================================== - - /** @deprecated: use LPrototype.source or LPrototype.sourceshort() instead */ - public String getSourceFileName(LString s) { - return getSourceFileName(s.toJavaString()); - } - - /** @deprecated: use LPrototype.source or LPrototype.sourceshort() instead */ - protected String getSourceFileName(String s) { - return LoadState.getSourceName(s); - } - - /** - * Get the file line number info for a particular call frame. - * @param cindex index into call stack, or -1 to get first lua location - * @return - */ - protected String getFileLine(int level) { - LClosure c = null; - for (int j=cc; j>=0; --j) { - CallInfo ci = calls[j]; - LFunction f = ci.currentfunc(this); - if ( f != null && (!f.isClosure() || f!=c) ) { - if ( level != -1 && (level--) <= 0 ) { - return "[Java]: "+f.toString(); - } - } - c = ci.closure; - if ( (level--) <= 0 ) { - return c.p.sourceshort()+":"+ci.currentline(); - } - } - return ""; - } - - /** - * Raises an error. The message is pushed onto the stack and used as the error message. - * It also adds at the beginning of the message the file name and the line number where - * the error occurred, if this information is available. - * - * In the java implementation this throws a LuaErrorException - * after filling line number information first when level > 0. - */ - public void error(String message, int level) { - throw new LuaErrorException( this, message, level ); - } - - /** - * Raises an error with the default level. - */ - public void error(String message) { - throw new LuaErrorException( this, message, -1 ); - } - - /** - * - * Ensures that there are at least extra free stack slots in - * the stack. [-0, +0, -] - * - *

- * It returns false if it cannot grow the stack to that size. This function - * never shrinks the stack; if the stack is already larger than the new - * size, it is left unchanged. - * - */ - public void checkstack(int extra) { - if ( top + extra >= stack.length ) { - int n = Math.max( top + extra + LUA_MINSTACK, stack.length * 2 ); - LValue[] s = new LValue[n]; - System.arraycopy(stack, 0, s, 0, stack.length); - stack = s; - } - } - - /** - * Dereference a tables field. [-0, +1, e] - * - *

- * Pushes onto the stack the value t[k], where - * t is the value at the given valid index. As in Lua, this - * function may trigger a metamethod for the "index" event (see §2.8). - * - */ - public void getfield(int index, LString k) { - pushlvalue( this.luaV_gettable(topointer(index), k) ); - } - - /** - * Look up a global value. [-0, +1, e] - * - *

- * Pushes onto the stack the value of the global name. It is - * defined as a macro: - * - *

-	 * 	 #define lua_getglobal(L,s)  lua_getfield(L, LUA_GLOBALSINDEX, s)
-	 * 	
-	 * 
- */ - public void getglobal(String s) { - pushlvalue( this.luaV_gettable(_G, new LString(s)) ); - } - - /** - * Get a value's metatable. [-0, +(0|1), -] - * - *

- * Pushes onto the stack the metatable of the value at the given acceptable - * index. If the index is not valid, or if the value does not have a - * metatable, the function returns false and pushes nothing on the stack. - * - * @return true if the metatable was pushed onto the stack, false otherwise - */ - public boolean getmetatable(int index) { - LTable mt = topointer(index).luaGetMetatable(); - if ( mt != null ) { - pushlvalue( mt ); - return true; - } - return false; - } - - /** - * Insert the top item somewhere in the stack. [-1, +1, - * -] - * - *

- * Moves the top element into the given valid index, shifting up the - * elements above this index to open space. Cannot be called with a - * pseudo-index, because a pseudo-index is not an actual stack position. - * - */ - public void insert(int index) { - int ai = index2adr(index); - LValue v = stack[top-1]; - System.arraycopy(stack, ai, stack, ai+1, top-ai-1); - stack[ai] = v; - } - - /** - * Test if a value is boolean. [-0, +0, -] - * - *

- * Returns 1 if the value at the given acceptable index has type boolean, - * and 0 otherwise. - * - */ - public boolean isboolean(int index) { - return type(index) == Lua.LUA_TBOOLEAN; - } - - /** - * Test if a value is a function. [-0, +0, -] - * - *

- * Returns true if the value at the given acceptable index is a function - * (either C or Lua), and false otherwise. - * - */ - public boolean isfunction(int index) { - return type(index) == Lua.LUA_TFUNCTION; - } - - /** - * Test if a value is nil [-0, +0, -] - * - *

- * Returns 1 if the value at the given acceptable index is nil, and - * 0 otherwise. - */ - public boolean isnil(int index) { - return topointer(index).isNil(); - } - - /** - * Test if a value is nil or not valid [-0, +0, - * -] - * - *

- * Returns 1 if the the given acceptable index is not valid (that is, it - * refers to an element outside the current stack) or if the value at this - * index is nil, and 0 otherwise. - */ - public boolean isnoneornil(int index) { - Object v = topointer(index); - return v == null || v == LNil.NIL; - } - - /** - * Test if a value is a number [-0, +0, -] - * - *

- * Returns 1 if the value at the given acceptable index is a number or a - * string convertible to a number, and 0 otherwise. - */ - public boolean isnumber(int index) { - return ! tolnumber(index).isNil(); - } - - /** - * Convert a value to an LNumber[-0, +0, -] - * - *

- * Returns an LNumber if the value at the given acceptable index is a number or a - * string convertible to a number, and LNil.NIL otherwise. - */ - public LValue tolnumber(int index) { - return topointer(index).luaToNumber(); - } - - /** - * Test if a value is a string [-0, +0, m] - * - *

- * Returns 1 if the value at the given acceptable index is a string or a - * number (which is always convertible to a string), and 0 otherwise. - */ - public boolean isstring(int index) { - return topointer(index).isString(); - } - - /** - * Test if a value is a table [-0, +0, -] - * - *

- * Returns 1 if the value at the given acceptable index is a table, and - * 0 otherwise. - */ - public boolean istable(int index) { - return topointer(index).isTable(); - } - - /** - * Test if a value is a thread [-0, +0, -] - * - *

- * Returns 1 if the value at the given acceptable index is a thread, and - * 0 otherwise. - */ - public boolean isthread(int index) { - return type(index) == Lua.LUA_TTHREAD; - } - - /** - * Test if a value is a userdata [-0, +0, -] - * - *

- * Returns 1 if the value at the given acceptable index is a userdata - * (either full or light), and 0 otherwise. - */ - public boolean isuserdata(int index) { - return type(index) == Lua.LUA_TUSERDATA; - } - - /** - * Pops n elements from the stack. [-n, - * +0, -] - */ - public void pop(int n) { - for ( int i=0; i[-0, +1, - * m] - */ - public void pushlvalue(LValue value) { - if ( value == null ) - throw new java.lang.IllegalArgumentException("stack values cannot be null"); - try { - stack[top] = value; - } catch ( java.lang.ArrayIndexOutOfBoundsException aiobe ) { - checkstack( LUA_MINSTACK ); - stack[top] = value; - } finally { - ++top; - } - } - - /** - * Pushes a boolean value with value b onto the stack. [-0, +1, -] - * - */ - public void pushboolean(boolean b) { - pushlvalue( LBoolean.valueOf(b) ); - } - - /** - * Pushes a number with value n onto the stack. [-0, +1, -] - */ - public void pushinteger(int n) { - pushlvalue( LInteger.valueOf(n) ); - } - - /** - * Pushes a function onto the stack. [-0, +1, - * m] - * - *

- * This function receives an LFunction and pushes onto the - * stack a Lua value of type function that, when called, - * invokes the corresponding function. - * - * - *

- * Any function to be registered in Lua must follow the correct protocol to - * receive its parameters and return its results - * @see LFunction - */ - public void pushfunction(LFunction f) { - pushlvalue( f ); - } - - - /** - * Push an LString onto the stack. [-0, +1, - * m] - */ - public void pushlstring(LString s) { - pushlvalue(s); - } - - /** - * Push string bytes onto the stack as a string. [-0, +1, - * m] - * - * Pushes the string pointed to by s with size - * len onto the stack. Lua makes (or reuses) an internal copy - * of the given string, so the memory at s can be freed or - * reused immediately after the function returns. The string can contain - * embedded zeros. - */ - public void pushlstring(byte[] bytes, int offset, int length) { - pushlvalue(new LString(bytes, offset, length)); - } - - /** - * Push string bytes onto the stack as a string. [-0, +1, - * m] - * - * Pushes the bytes in byteArray onto the stack as a lua string. - */ - public void pushlstring(byte[] byteArray) { - pushlstring(byteArray, 0, byteArray.length); - } - - /** - * Pushes a nil value onto the stack. [-0, +1, -] - * - */ - public void pushnil() { - pushlvalue(LNil.NIL); - } - - /** - * Pushes a number with value d onto the stack. [-0, +1, -] - * - */ - public void pushnumber(double d) { - pushlvalue(LDouble.numberOf(d)); - } - - /** - * Push a String onto the stack. [-0, +1, m] - * - *

- * Pushes the String s onto the stack. Lua makes (or reuses) - * an internal copy of the given string, so the memory at s - * can be freed or reused immediately after the function returns. The string - * cannot contain embedded zeros; it is assumed to end at the first zero. - */ - public void pushstring(String s) { - if ( s == null ) - pushnil(); - else - pushlstring( LString.valueOf(s) ); - } - - /** - * Push a value from the stack onto the stack. [-0, +1, - * -] - * - *

- * Pushes a copy of the element at the given valid index onto the stack. - */ - public void pushvalue(int index) { - pushlvalue(topointer(index)); - } - - /** - * Do a integer-key table get without metadata calls. [-0, +1, -] - * - *

- * Pushes onto the stack the value t[n], where - * t is the value at the given valid index. The access is - * raw; that is, it does not invoke metamethods. - * @deprecated should get the table and do a raw get instead - */ - public void rawgeti(int index, int n) { - pushlvalue( totable(index).get(n) ); - } - - /** - * Remove an element from the stack. [-1, +0, -] - * - *

- * Removes the element at the given valid index, shifting down the elements - * above this index to fill the gap. Cannot be called with a pseudo-index, - * because a pseudo-index is not an actual stack position. - */ - public void remove(int index) { - int ai = index2adr(index); - System.arraycopy(stack, ai+1, stack, ai, top-ai-1); - poplvalue(); - } - - /** - * Replace an element on the stack. [-1, +0, -] - * - *

- * Moves the top element into the given position (and pops it), without - * shifting any element (therefore replacing the value at the given - * position). - */ - public void replace(int index) { - int ai = index2adr(index); - stack[ai] = poplvalue(); - } - - /** - * Set the value of a table field. [-1, +0, e] - * - *

- * Does the equivalent to t[k] = v, where t - * is the value at the given valid index and v is the value - * at the top of the stack. - * - * - *

- * This function pops the value from the stack. As in Lua, this function may - * trigger a metamethod for the "newindex" event (see §2.8). - */ - public void setfield(int index, LString k) { - LTable t = totable(index); - this.luaV_settable(t, k, poplvalue()); - } - - /** - * Set the value of a global variable. [-1, +0, - * e] - * - *

- * Pops a value from the stack and sets it as the new value of global - * name. It is defined as a macro: - * - *

-	 * 	 #define lua_setglobal(L,s)   lua_setfield(L, LUA_GLOBALSINDEX, s)
-	 * 	
-	 * 
- */ - public void setglobal(String name) { - this.luaV_settable(_G, new LString(name), poplvalue()); - } - - /** - * Get a value as a boolean. [-0, +0, -] - * - *

- * Converts the Lua value at the given acceptable index to a C boolean - * value (0 or 1). Like all tests in Lua, lua_toboolean returns 1 for - * any Lua value different from false and nil; otherwise it - * returns 0. It also returns 0 when called with a non-valid index. (If you - * want to accept only actual boolean values, use lua_isboolean - * to test the value's type.) - * - */ - public boolean toboolean(int index) { - return topointer(index).toJavaBoolean(); - } - - /** - * Get a value as an int. [-0, +0, -] - * - *

- * Converts the Lua value at the given acceptable index to the signed - * integral type lua_Integer. - * The Lua value must be a number or a string convertible to a number (see - * §2.2.1); otherwise, lua_tointeger - * returns 0. - * - * - *

- * If the number is not an integer, it is truncated in some non-specified - * way. - */ - public int tointeger(int index) { - LValue v = tolnumber(index); - return v.isNil()? 0: v.toJavaInt(); - } - - /** - * Get a value as a LFunction. - *


- *

tofunction

- *

- * [-0, +0, -] - * - *

-	 * LFunction tofunction (lua_State *L, int index);
-	 * 
- * - *

- * Converts a value at the given acceptable index to a C function. That - * value must be a function; otherwise, returns NULL. - */ - public LValue tofunction(int index) { - LValue v = topointer(index); - return v.isFunction()? v: LNil.NIL; - } - - /** - * Gets the value of a string as byte array. [-0, +0, - * m] - * - *

- * Converts the Lua value at the given acceptable index to a C string. - * If len is not NULL, it also sets - * *len with the string length. The Lua value must be a - * string or a number; otherwise, the function returns NULL. - * If the value is a number, then lua_tolstring - * also changes the actual value in the stack to a string. (This - * change confuses lua_next when lua_tolstring is applied to - * keys during a table traversal.) - * - * - *

- * lua_tolstring returns a - * fully aligned pointer to a string inside the Lua state. This string - * always has a zero ('\0') after its last character (as - * in C), but may contain other zeros in its body. Because Lua has - * garbage collection, there is no guarantee that the pointer returned by lua_tolstring will be valid - * after the corresponding value is removed from the stack. - */ - public LString tolstring(int index) { - return topointer(index).luaAsString(); - } - - /** - * Convert a value to a double. [-0, +0, -] - * - *

- * Converts the Lua value at the given acceptable index to the C type - * lua_Number (see lua_Number). The Lua value must - * be a number or a string convertible to a number (see §2.2.1); otherwise, lua_tonumber - * returns 0. - * - */ - public double tonumber(int index) { - LValue v = tolnumber(index); - return v.isNil()? 0: v.toJavaDouble(); - } - - /** - * Returns the index of the top element in the stack. [-0, +0, -] - * - *

- * Because indices start at 1, this result is equal to the number of - * elements in the stack (and so 0 means an empty stack). - */ - public int gettop() { - return top - base; - } - - /** - * Set the top of the stack. [-?, +?, -] - * - *

- * Accepts any acceptable index, or 0, and sets the stack top to this - * index. If the new top is larger than the old one, then the new elements - * are filled with nil. If index is 0, then all - * stack elements are removed. - */ - public void settop(int nt) { - int ant = nt>=0? base+nt: top+nt; - if ( ant < base ) - throw new IllegalArgumentException("index out of bounds: "+ant ); - luaV_adjusttop(ant); - } - - - /** - * Set the top to the base. Equivalent to settop(0) - */ - public void resettop() { - luaV_settop_fillabove( base ); - } - - private int index2adr(int index) { - // TODO: upvalues? globals? environment? - int ai = index>0? base+index-1: top+index; - if ( ai < base ) - throw new IllegalArgumentException("index out of bounds: "+ai ); - return ai; - } - - /** - * Get the raw Object at a stack location. [-0, +0, - * -] - * - *

- * Converts the value at the given acceptable index to a generic - * C pointer (void*). The value may be a userdata, a - * table, a thread, or a function; otherwise, lua_topointer - * returns NULL. Different objects will give different - * pointers. There is no way to convert the pointer back to its original - * value. - * - * - *

- * Typically this function is used only for debug information. - */ - public LValue topointer(int index) { - int ai = index2adr(index); - if ( ai >= top ) - return LNil.NIL; - return stack[ai]; - } - - /** - * Get a stack value as a String. [-0, +0, m] - * - *

- * Equivalent to lua_tolstring - * with len equal to NULL. - */ - public String tostring(int index) { - return topointer(index).toJavaString(); - } - - /** - * Get a value from the stack as a lua table. [-0, +0, -] - * - *

- * Converts the value at the given acceptable index to a Lua table - * This value must be a table otherwise, the function returns NIL. - */ - public LTable totable(int index) { - return (LTable) topointer(index); - } - - /** - * Get the Object from a userdata value. [-0, +0, - * -] - * - *

- * If the value at the given acceptable index is a full userdata, returns - * its block address. If the value is a light userdata, returns its pointer. - * Otherwise, returns NULL. - * - */ - public Object touserdata(int index) { - LValue v = topointer(index); - if ( v.luaGetType() != Lua.LUA_TUSERDATA ) - return null; - return ((LUserData)v).m_instance; - } - - /** - * Get the type of a value. [-0, +0, -] - * - *

- * Returns the type of the value in the given acceptable index, or - * LUA_TNONE for a non-valid index (that is, an index to an - * "empty" stack position). The types returned by lua_type - * are coded by the following constants defined in lua.h: - * LUA_TNIL, LUA_TNUMBER, - * LUA_TBOOLEAN, LUA_TSTRING, - * LUA_TTABLE, LUA_TFUNCTION, - * LUA_TUSERDATA, LUA_TTHREAD, and - * LUA_TLIGHTUSERDATA. - */ - public int type(int index) { - return topointer(index).luaGetType(); - } - - /** - * Get the type name for a value. [-0, +0, -] - * - *

- * Returns the name of the type encoded by the value tp, - * which must be one the values returned by lua_type. - */ - public String typename(int index) { - return topointer(index).luaGetTypeName().toJavaString(); - } - - /** - * Exchange values between threads. [-?, +?, -] - * - *

- * Exchange values between different threads of the same global - * state. - * - * - *

- * This function pops n values from the stack - * from, and pushes them onto the stack to. - */ - public void xmove(LuaState to, int n) { - if ( n > 0 ) { - to.checkstack(n); - LuaState ss = (LuaState)to; - ss.checkstack(n); - System.arraycopy(stack, top-n, ss.stack, ss.top, n); - ss.top += n; - } - } - - // ============================= conversion to and from Java boxed types ==================== - - /** - * Push a Java Boolean value, or nil if the value is null. - * @param b Boolean value to convert, or null to to nil. - */ - public void pushboolean(Boolean b) { - if ( b == null ) - pushnil(); - else - pushboolean( b.booleanValue() ); - } - - /** - * Push a Java Byte value, or nil if the value is null. - * @param b Byte value to convert, or null to to nil. - */ - public void pushinteger(Byte b) { - if ( b == null ) - pushnil(); - else - pushinteger( b.byteValue() ); - } - - /** - * Push a Java Character value, or nil if the value is null. - * @param c Character value to convert, or null to to nil. - */ - public void pushinteger(Character c) { - if ( c == null ) - pushnil(); - else - pushinteger( c.charValue() ); - } - - /** - * Push a Java Double as a double, or nil if the value is null. - * @param d Double value to convert, or null to to nil. - */ - public void pushnumber(Double d) { - if ( d == null ) - pushnil(); - else - pushnumber( d.doubleValue() ); - } - - /** - * Push a Java Float value, or nil if the value is null. - * @param f Float value to convert, or null to to nil. - */ - public void pushnumber(Float f) { - if ( f == null ) - pushnil(); - else - pushnumber( f.doubleValue() ); - } - - /** - * Push a Java Integer value, or nil if the value is null. - * @param i Integer value to convert, or null to to nil. - */ - public void pushinteger(Integer i) { - if ( i == null ) - pushnil(); - else - pushinteger( i.intValue() ); - } - - /** - * Push a Java Short value, or nil if the value is null. - * @param s Short value to convert, or null to to nil. - */ - public void pushinteger(Short s) { - if ( s == null ) - pushnil(); - else - pushinteger( s.shortValue() ); - } - - /** - * Push a Java Long value, or nil if the value is null. - * @param l Long value to convert, or null to to nil. - */ - public void pushnumber(Long l) { - if ( l == null ) - pushnil(); - else - pushnumber( l.doubleValue() ); - } - - /** - * Push a Java Object as userdata, or nil if the value is null. - * @param o Object value to push, or null to to nil. - */ - public void pushuserdata( Object o ) { - if ( o == null ) - pushnil(); - else - pushlvalue( new LUserData(o) ); - } - - - /** - * Convert a value to a Java Boolean value, or null if the value is nil. - * @param index index of the parameter to convert. - * @return Boolean value at the index, or null if the value was not a boolean. - */ - public Boolean toboxedboolean(int index) { - return topointer(index).toJavaBoxedBoolean(); - } - - /** - * Convert a value to a Java Byte value, or null if the value is not a number. - * @param index index of the parameter to convert. - * @return Byte value at the index, or null if the value was not a number. - */ - public Byte toboxedbyte(int index) { - return topointer(index).toJavaBoxedByte(); - } - - /** - * Convert a value to a Java Double value, or null if the value is not a number. - * @param index index of the parameter to convert. - * @return Double value at the index, or null if the value was not a number. - */ - public Double toboxeddouble(int index) { - return topointer(index).toJavaBoxedDouble(); - } - - /** - * Convert a value to a Java Float value, or null if the value is not a number. - * @param index index of the parameter to convert. - * @return Float value at the index, or null if the value was not a boolean. - */ - public Float toboxedfloat(int index) { - return topointer(index).toJavaBoxedFloat(); - } - - /** - * Convert a value to a Java Integer value, or null if the value is not a number. - * @param index index of the parameter to convert. - * @return Integer value at the index, or null if the value was not a number. - */ - public Integer toboxedinteger(int index) { - return topointer(index).toJavaBoxedInteger(); - } - - /** - * Convert a value to a Java Long value, or null if the value is nil. - * @param index index of the parameter to convert. - * @return Long value at the index, or null if the value was not a number. - */ - public Long toboxedlong(int index) { - return topointer(index).toJavaBoxedLong(); - } - - // ================= Error Reporting Functions ================= - - /** - * Report an error with an argument. - * - * @param narg Stack index of the bad argument - * @param extramsg String to include in error message - */ - public void argerror(int narg, String extramsg) { - error("bad argument #" + (narg) + " (" + extramsg + ")"); - } - - /** - * Conditionally report an error with an argument. - * - * @param cond boolean condition that generates an error when false - * @param narg Stack index of the bad argument - * @param extramsg String to include in error message - */ - public void argcheck(boolean cond, int narg, String extramsg) { - if ( ! cond ) - argerror(narg,extramsg); - } - - /** - * Report a type error. - * - * @param narg Stack index of the bad argument - * @param typename Name of the type that was expected, such as "string" - */ - public void typerror(int narg, String typename) { - argerror(narg, typename + " expected, got " + typename(narg)); - } - - /** - * Report a type error. - * - * @param narg Stack index of the bad argument - * @param typenum Constant value specifying the type of argument that was expected (i.e. LUA_TSTRING). - */ - public void typerror(int narg, int typenum) { - typerror(narg, TYPE_NAMES[typenum]); - } - - - /** - * Checks whether the function has an argument of any type (including nil) - * at position narg. - * @param narg the argument number - * @return the value at the index - * @throws LuaErrorException if there is no argument at position narg - */ - public LValue checkany(int narg) { - if ( gettop() < narg ) - argerror(narg, "value expected"); - return topointer(narg); - } - - /** - * Checks whether the function argument narg is a function and - * returns this function. - * @see LFunction - * @param narg the argument number - * @throws LuaErrorException if the value is not a function - * @return LFunction value if the argument is a function - */ - public LFunction checkfunction(int narg) { - return (LFunction) checktype(narg, Lua.LUA_TFUNCTION); - } - - /** - * Checks whether the function argument narg is a thread and - * returns this thread. - * @see LThread - * @param narg the argument number - * @throws LuaErrorException if the value is not a thread - * @return LThread value if the argument is a thread - */ - public LThread checkthread(int narg) { - return (LThread) checktype(narg, Lua.LUA_TTHREAD); - } - - /** - * Checks whether the function argument narg is a number and - * returns this number cast to an int. - * @param narg the argument number - * @throws LuaErrorException if the number cannot be converted to an int - * @return int value if the argument is an int or can be converted to one - */ - public int checkint(int narg) { - LValue v = tolnumber(narg); - if ( v.isNil() ) - typerror(narg, Lua.LUA_TNUMBER); - return v.toJavaInt(); - } - - /** - * Checks whether the function argument narg is a number and - * returns this number cast to a LInteger. - * @see LInteger - * @param narg the argument number - * @throws LuaErrorException if the value cannot be converted to an int - * @return LInteger value if the argument is an int or can be converted to one - */ - public LInteger checkinteger(int narg) { - return LInteger.valueOf(checkint(narg)); - } - - /** - * Checks whether the function argument narg is a number and - * returns this number cast to a long. - * @param narg the argument number - * @throws LuaErrorException if the value cannot be converted to a long - * @return long value if the argument is a number or can be converted to long - */ - public long checklong(int narg) { - return checknumber(narg).toJavaLong(); - } - - /** - * Checks whether the function argument narg is a number and - * returns this number cast to a double. - * @param narg the argument number - * @throws LuaErrorException if the value cannot be converted to a double - * @return long value if the argument is a number or can be converted to double - */ - public double checkdouble(int narg) { - return checknumber(narg).toJavaDouble(); - } - - /** - * Checks whether the function argument narg is a number and - * returns this number. - * @see LNumber - * @param narg the argument number - * @throws LuaErrorException if the value cannot be converted to a number - * @return LNumber value if the argument is a number or can be converted to one - */ - public LNumber checknumber(int narg) { - LValue v = topointer(narg).luaToNumber(); - if ( v.isNil() ) - typerror(narg, Lua.LUA_TNUMBER); - return (LNumber) v; - } - - /** - * Checks whether the function argument narg is a string and - * returns this string as a lua string. - * @see LString - * @param narg the argument number - * @throws LuaErrorException if the value cannot be converted to a string - * @return LString value if the argument is a string or can be converted to one - */ - public LString checklstring(int narg) { - LValue v = topointer(narg); - if ( ! v.isString() ) - typerror(narg, Lua.LUA_TSTRING); - return v.luaAsString(); - } - - /** - * Checks whether the function argument narg is a string and - * returns this string as a Java String. - * @param narg the argument number - * @throws LuaErrorException if the value cannot be converted to a string - * @return String value if the argument is a string or can be converted to one - */ - public String checkstring(int narg) { - LValue v = topointer(narg); - if ( ! v.isString() ) - typerror(narg, Lua.LUA_TSTRING); - return v.toJavaString(); - } - - /** - * Checks whether the function argument narg is a table and - * returns this table. - * @see LTable - * @param narg the argument number - * @throws LuaErrorException if the value is not a table - * @return LTable value if the argument is a table - */ - public LTable checktable(int narg) { - return (LTable) checktype(narg, Lua.LUA_TTABLE); - } - - /** - * Checks whether the function argument narg has type - * t and return it as an LValue. - * @param narg the argument number - * @param t the type number to check against - * @return the lua value - * @throws LuaErrorException if the value is not of type t - */ - public LValue checktype(int narg, int t) { - LValue v = topointer(narg); - if ( v.luaGetType() != t ) - typerror(narg, t); - return v; - } - - - /** - * Check that the type of userdata on the stack matches the required type, - * and if so, return the Java Object the userdata value points to. - * - * @param ud - * Stack index of the argument to check - * @param expected - * Class that the userdata is expected to have an instance of. - */ - public Object checkudata(int ud, Class expected) { - Object p = touserdata(ud); - if (expected.isInstance(p)) { - return p; - } - typerror(ud, expected.getName()); - return null; - } - - /** - * If the function argument narg is a number, returns this - * number cast to an int. If this argument is absent or is - * nil, returns d. Otherwise, raises an error. - * @param narg the argument number - * @param d the default value when the argument is nil or not supplied - * @throws LuaErrorException if the value cannot be converted to an int - * @return int value if the argument is an int, or d - */ - public int optint(int narg, int d) { - LNumber n = optnumber(narg,null); - return (n==null? d: n.toJavaInt()); - } - - /** - * If the function argument narg is a number, returns this - * number cast to a lua_Integer. - * If this argument is absent or is nil, returns d. - * Otherwise, raises an error. - * @param narg the argument number - * @param d the default value when the argument is nil or not supplied - * @throws LuaErrorException if the value cannot be converted to an int - * @return int value if the argument is an int, or d - */ - public LInteger optinteger(int narg, int d) { - return LInteger.valueOf(optint(narg,d)); - } - - /** - * If the function argument narg is a number, returns this - * number cast to a long. If this argument is absent or is - * nil, returns d. Otherwise, raises an error. - * @param narg the argument number - * @param d the default value when the argument is nil or not supplied - * @throws LuaErrorException if the value cannot be converted to an number - * @return int value if the argument is an number, or d - */ - public long optlong(int narg, long d) { - LNumber n = optnumber(narg,null); - return (n==null? d: n.toJavaLong()); - } - - /** - * If the function argument narg is a number, returns this - * number. If this argument is absent or is nil, returns - * d. Otherwise, raises an error. - * @param narg the argument number - * @param d the default value when the argument is nil or not supplied - * @throws LuaErrorException if the value cannot be converted to an number - * @return int value if the argument is an number, or d - */ - public LNumber optnumber(int narg, LNumber d) { - LValue v = topointer(narg); - if ( v.isNil() ) - return d; - v = v.luaToNumber(); - if ( v.isNil() ) - typerror(narg, Lua.LUA_TNUMBER); - return (LNumber) v; - - } - - /** - * If the function argument narg is a string, returns this - * string. If this argument is absent or is nil, returns - * d. Otherwise, raises an error. - */ - public LString optlstring(int narg, LString d) { - LValue v = topointer(narg); - if ( v.isNil() ) - return d; - if ( ! v.isString() ) - typerror(narg, Lua.LUA_TSTRING); - return v.luaAsString(); - } - - /** - * If the function argument narg is a string, returns this - * string. If this argument is absent or is nil, returns - * d. Otherwise, raises an error. - */ - public String optstring(int narg, String d) { - LValue v = topointer(narg); - if ( v.isNil() ) - return d; - if ( ! v.isString() ) - typerror(narg, Lua.LUA_TSTRING); - return v.toJavaString(); - } - - /** - * Method to indicate a vm internal error has occurred. Generally, this is - * not recoverable, so we convert to a lua error during production so that - * the code may recover. - */ - public static void vmerror(String description) { - throw new LuaErrorException( "internal error: "+description ); - } - - /** - * Call a function with no arguments and one return value. - * This may change values in the current stack frame. - * @param function - * @return - */ - public LValue call(LFunction function) { - pushlvalue(function); - call(0,1); - return poplvalue(); - } - - /** - * Call a function with one argument and one return value - * This may change values in the current stack frame. - * @param function - * @param arg0 - * @return - */ - public LValue call(LFunction function, LValue arg0) { - pushlvalue(function); - pushlvalue(arg0); - call(1,1); - return poplvalue(); - } - - /** - * Call an index function with two arguments and one return value - * Values in the current stack frame will be preserved. - * @param function the __index function to call - * @param table the table on which the metadata operation is taking place - * @param key the key used in the index operation - * @return the value that results from the metatable operation - */ - public LValue luaV_call_index(LFunction function, LValue table, LValue key) { - int oldtop = top; - try { - if ( cc >= 0 ) - top = base + this.calls[cc].closure.p.maxstacksize; - pushlvalue(function); - pushlvalue(table); - pushlvalue(key); - call(2,1); - return poplvalue(); - } finally { - top = oldtop; - } - } - - /** - * Call a newindex function with three arguments and one return value - * Values in the current stack frame will be preserved. - * @param function the __newindex function to call - * @param table the table on which the metadata operation is taking place - * @param key the key used in the newindex operation - * @param value the value beting set in the newindex operation - * @return the value that results from the metatable operation - */ - public LValue luaV_call_newindex(LFunction function, LValue table, LValue key, LValue value) { - int oldtop = top; - try { - if ( cc >= 0 ) - top = base + this.calls[cc].closure.p.maxstacksize; - pushlvalue(function); - pushlvalue(table); - pushlvalue(key); - pushlvalue(value); - call(3,1); - return poplvalue(); - } finally { - top = oldtop; - } - } - - - /** - * Call the error function, if any, to possibly modify the message - */ - public String luaV_call_errfunc(String message) { - - // error function runs without hooks - if ( inhook || errfunc == null ) - return message; - - // run the error function - int oldtop = top; - try { - inhook = true; - if ( cc >= 0 ) - top = base + this.calls[cc].closure.p.maxstacksize; - pushlvalue(errfunc); - pushstring(message); - call(1,1); - return poplvalue().toJavaString(); - - } catch ( Throwable t ) { - return "error in error handling: "+t.getMessage(); - - } finally { - top = oldtop; - inhook = false; - } - } - - - // =========================================================================== - // Debug hooks. - // These should be obfuscated out when sethook is never called - // cannot be called from the application. - // - - /** - * Set the hook function. - * - * @param func LFunction to call on the hook event - * @param mask combination of LuaState.LUA_MASKLINE, LuaState.LUA_MASKCALL, and LuaState.LUA_MASKRET - * @param count 0, or number of bytecodes between count events. - */ - public void sethook( LFunction func, int mask, int count ) { - hooksenabled = (mask != 0 || count > 0); - hookfunc = func; - hookmask = mask; - hookcount = count; - } - - /** - * Get the current hook function, if any. - * - * @return LFunction that is set as the current hook function, or null if not set. - */ - public LFunction gethook() { - return hookfunc; - } - - /** - * Get the current hook count. - * - * @return current count, which is # of bytecodes between "count" hook calls - */ - public int gethookcount() { - return hookcount; - } - - /** - * Get the current hook mask. - * - * @return current mask as a combination of - * LuaState.LUA_MASKLINE, LuaState.LUA_MASKCALL, and LuaState.LUA_MASKRET - */ - public int gethookmask() { - return hookmask; - } - - // line number and count hooks - private void debugBytecodeHooks(int pc) { - if ( hookfunc != null ) { - if (hookcount != 0) { - if ( --hookincr <= 0 ) { - hookincr = hookcount; - debugInvokeHook(LUA_HOOKCOUNT, -1); - } - } - if ( (hookmask & LUA_MASKLINE) != 0 ) { - int line = calls[cc].currentline(); - if ( (line != hookline || cc != hookcc) && line >= 0 ) { - hookline = line; - hookcc = cc; - debugInvokeHook(LUA_HOOKLINE, line); - } - } - } - } - - private void debugCallHooks() { - if ( hookfunc != null && ((hookmask & LUA_MASKCALL) != 0) ) { - debugInvokeHook(LUA_HOOKCALL, calls[cc].currentline()); - } - } - - private void debugReturnHooks() { - if ( hookfunc != null && ((hookmask & LUA_MASKRET) != 0) ) { - debugInvokeHook(LUA_HOOKRET, calls[cc].currentline()); - } - } - - private void debugTailReturnHooks() { - if ( hookfunc != null && ((hookmask & LUA_MASKRET) != 0) ) { - debugInvokeHook(LUA_HOOKTAILRET, calls[cc].currentline()); - } - } - - private void debugInvokeHook(int mask, int line) { - if ( inhook ) - return; - int oldtop = top; - int oldbase = base; - int oldcc = cc; - int oldnresults = nresults; - int beyond = (cc>=0? base+calls[cc].closure.p.maxstacksize: top); - try { - inhook = true; - - // adjust base and top to beyond call frame - top = base = beyond; - - // push hook function and arguments - this.pushfunction(hookfunc); - switch ( mask ) { - case LUA_HOOKCOUNT: this.pushstring("count"); break; - case LUA_HOOKCALL: this.pushstring("call"); break; - case LUA_HOOKRET: this.pushstring("return"); break; - case LUA_HOOKTAILRET: this.pushstring("tail return"); break; - default: - this.pushstring("line"); - this.pushinteger(line); - break; - } - - // make or set up the call - this.nresults = 0; - if ( this.stack[base].luaStackCall(this) ) - execute(); - - } catch ( Throwable t ) { - System.err.println("hook exception: "+t); - } finally { - luaV_settop_fillabove(beyond); - cc = oldcc; - base = oldbase; - top = oldtop; - nresults = oldnresults; - inhook = false; - } - } -} diff --git a/src/core/org/luaj/vm/Platform.java b/src/core/org/luaj/vm/Platform.java deleted file mode 100644 index 3ef1cda9..00000000 --- a/src/core/org/luaj/vm/Platform.java +++ /dev/null @@ -1,186 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007 LuaJ. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ -package org.luaj.vm; - -import java.io.InputStream; -import java.io.Reader; - -/** - * Singleton to manage platform-specific behaviors. - *

- * Here is the sample code to set up the platform instance and create a new - * LuaState instance. - *

- *    Platform.setInstance(new J2meMidp20Cldc11Platform());
- *    LuaState vm = Platform.newLuaState();
- * 
- */ -abstract public class Platform { - - /** - * When non-null, name of a Java Class that implements LuaState - * and has a default constructor which will be used to construct - * a new lua state using Platform.newLuaState() - * @see newLuaState - */ - public static String LUA_STATE_CLASS_NAME = null; - - /** - * The singleton Platform instance in use by this JVM - */ - private static Platform instance; - - - /** - * Singleton to be used for platform operations. - * - * The default Platform gets files as resources, and converts them to - * characters using the default InputStreamReader class. - */ - public static Platform getInstance() { - if (instance == null) { - throw new RuntimeException("Platform instance is null. Use Platform.setInstance(Platform p) to set the instance first."); - } - - return instance; - } - - /** - * Set the Platform instance. - * - * This may be useful to define a file search path, or custom character - * encoding conversion properties. - */ - public static void setInstance(Platform platform) { - instance = platform; - } - - /** - * Creates a new instance of LuaState. - * - * If Platform.LUA_STATE_CLASS_NAME is not null, this method - * will attempt to create an instance using a construction such as - * (LuaState) Class.forName(Platform.LUA_STATE_CLASS_NAME).newInstance() - * - * If Platform.LUA_STATE_CLASS_NAME is null or the specified class cannot - * be instantiated for some reason, a new instance of LuaState - * will be created and used. - * - * In either case, the method LuaState.init() will be invoked, followed by - * Platform.installOptionalProperties(LuaState) on the new instance. - * - * @return a new instance of LuaState initialized via init() and installOptionalProperties() - * - * @see LUA_STATE_CLASS_NAME - * @see LuaState - */ - public static LuaState newLuaState() { - Platform p = Platform.getInstance(); - LuaState vm = null; - if (LUA_STATE_CLASS_NAME != null) { - try { - vm = (LuaState) Class.forName(LUA_STATE_CLASS_NAME).newInstance(); - } catch (Exception e) { - System.out.println("Warning: no debug support, " + e); - } - } - - if (vm == null) - vm = new LuaState(); - - vm.init(); - p.installOptionalLibs(vm); - - return vm; - } - - /** Get the name of the platform - */ - abstract public String getName(); - - /** - * Return an InputStream or null if not found for a particular file name. - * - * @param fileName - * Name of the file to open - * @return InputStream or null if not found. - */ - abstract public InputStream openFile(String fileName); - - /** - * Create Reader from an InputStream - * - * @param inputStream - * InputStream to read from - * @return Reader instance to use for character input - */ - abstract public Reader createReader(InputStream inputStream); - - /** - * Returns the value for the given platform property. - * - * @param propertyName - * Property name - * @return Property value - */ - abstract public String getProperty(String propertyName); - - /** - * Install optional libraries on the LuaState. - * @param vm LuaState instance - */ - abstract protected void installOptionalLibs(LuaState vm); - - /** - * Compute math.pow() for two numbers using double math when available. - * @param lhs LNumber base - * @param rhs LNumber exponent - * @return base ^ exponent as a LNumber, throw RuntimeException if not implemented - */ - abstract public LNumber mathPow(LNumber base, LNumber exponent); - - /** - * Compute a math operation that takes a single double argument and returns a double - * @param id the math op, from MathLib constants - * @param x the argument - * @return the value as an LNumber - * @throws LuaErrorException if the id is not supported by this platform. - */ - abstract public LNumber mathop(int id, LNumber x); - - /** - * Compute a math operation that takes a two double arguments and returns a double - * @param id the math op, from MathLib constants - * @param x the first argument as an LNumber - * @param y the second arugment as an LNumber - * @return the value as an LNumber - * @throws LuaErrorException if the id is not supported by this platform. - */ - abstract public LNumber mathop(int id, LNumber x, LNumber y); - - - /** Throw an error indicating the math operation is not accepted */ - public LNumber unsupportedMathOp() { - throw new LuaErrorException("math op not supported on "+getName()); - } - -} diff --git a/src/core/org/luaj/vm/Print.java b/src/core/org/luaj/vm/Print.java deleted file mode 100644 index 5855ad32..00000000 --- a/src/core/org/luaj/vm/Print.java +++ /dev/null @@ -1,357 +0,0 @@ -package org.luaj.vm; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - - - - - -public class Print extends Lua { - - /** opcode names */ - private static final String STRING_FOR_NULL = "null"; - public static PrintStream ps = System.out; - - private static final String[] luaP_opnames = { - "MOVE", - "LOADK", - "LOADBOOL", - "LOADNIL", - "GETUPVAL", - "GETGLOBAL", - "GETTABLE", - "SETGLOBAL", - "SETUPVAL", - "SETTABLE", - "NEWTABLE", - "SELF", - "ADD", - "SUB", - "MUL", - "DIV", - "MOD", - "POW", - "UNM", - "NOT", - "LEN", - "CONCAT", - "JMP", - "EQ", - "LT", - "LE", - "TEST", - "TESTSET", - "CALL", - "TAILCALL", - "RETURN", - "FORLOOP", - "FORPREP", - "TFORLOOP", - "SETLIST", - "CLOSE", - "CLOSURE", - "VARARG", - null, - }; - - - static void printString(PrintStream ps, final LString s) { - final byte[] bytes = s.m_bytes; - final int off = s.m_offset; - - ps.print('"'); - for (int i = 0, n = s.m_length; i < n; i++) { - int c = bytes[i+off] & 0x0FF; - if ( c >= ' ' && c <= '~' && c != '\"' && c != '\\' ) - ps.print((char) c); - else { - switch (c) { - case '"': - ps.print("\\\""); - break; - case '\\': - ps.print("\\\\"); - break; - case 0x0007: /* bell */ - ps.print("\\a"); - break; - case '\b': /* backspace */ - ps.print("\\f"); - break; - case '\f': /* form feed */ - ps.print("\\f"); - break; - case '\r': /* carriage return */ - ps.print("\\r"); - break; - case '\n': /* newline */ - ps.print("\\n"); - break; - case 0x000B: /* vertical tab */ - ps.print("\\v"); - break; - default: - ps.print('\\'); - ps.print(Integer.toString(1000 + c).substring(1)); - break; - } - } - } - ps.print('"'); - } - - static void printValue( PrintStream ps, LValue v ) { - if ( v instanceof LString ) - printString( ps, v.luaAsString() ); - else if ( v instanceof LInteger ) { - ps.print( v.toJavaInt() ); - } else if ( v instanceof LDouble ) { - double d = v.toJavaDouble(); - if ( d == ((int)d) ) - ps.print( (int) d ); - else - ps.print( d ); - } else if ( v instanceof LFunction ) { - ps.print(v.getClass().getName()); - } else { - ps.print( String.valueOf(v) ); - } - } - - static void printConstant(PrintStream ps, LPrototype f, int i) { - printValue( ps, f.k[i] ); - } - - public static void printCode(LPrototype f) { - int[] code = f.code; - int pc, n = code.length; - for (pc = 0; pc < n; pc++) { - printOpCode(f, pc); - ps.println(); - } - } - - public static void printOpCode(LPrototype f, int pc) { - printOpCode(ps,f,pc); - } - - public static void printOpCode(PrintStream ps, LPrototype f, int pc) { - int[] code = f.code; - int i = code[pc]; - int o = GET_OPCODE(i); - int a = GETARG_A(i); - int b = GETARG_B(i); - int c = GETARG_C(i); - int bx = GETARG_Bx(i); - int sbx = GETARG_sBx(i); - int line = getline(f, pc); - ps.print(" " + (pc + 1) + " "); - if (line > 0) - ps.print("[" + line + "] "); - else - ps.print("[-] "); - ps.print(luaP_opnames[o] + " "); - switch (getOpMode(o)) { - case iABC: - ps.print( a ); - if (getBMode(o) != OpArgN) - ps.print(" "+(ISK(b) ? (-1 - INDEXK(b)) : b)); - if (getCMode(o) != OpArgN) - ps.print(" "+(ISK(c) ? (-1 - INDEXK(c)) : c)); - break; - case iABx: - if (getBMode(o) == OpArgK) { - ps.print(a + " " + (-1 - bx)); - } else { - ps.print(a + " " + (bx)); - } - break; - case iAsBx: - if (o == OP_JMP) - ps.print( sbx ); - else - ps.print(a + " " + sbx); - break; - } - switch (o) { - case OP_LOADK: - ps.print(" ; "); - printConstant(ps, f, bx); - break; - case OP_GETUPVAL: - case OP_SETUPVAL: - ps.print(" ; "); - if ( f.upvalues.length > b ) - printValue(ps, f.upvalues[b]); - else - ps.print( "-" ); - break; - case OP_GETGLOBAL: - case OP_SETGLOBAL: - ps.print(" ; "); - printConstant( ps, f, bx ); - break; - case OP_GETTABLE: - case OP_SELF: - if (ISK(c)) { - ps.print(" ; "); - printConstant(ps, f, INDEXK(c)); - } - break; - case OP_SETTABLE: - case OP_ADD: - case OP_SUB: - case OP_MUL: - case OP_DIV: - case OP_POW: - case OP_EQ: - case OP_LT: - case OP_LE: - if (ISK(b) || ISK(c)) { - ps.print(" ; "); - if (ISK(b)) - printConstant(ps, f, INDEXK(b)); - else - ps.print("-"); - ps.print(" "); - if (ISK(c)) - printConstant(ps, f, INDEXK(c)); - else - ps.print("-"); - } - break; - case OP_JMP: - case OP_FORLOOP: - case OP_FORPREP: - ps.print(" ; to " + (sbx + pc + 2)); - break; - case OP_CLOSURE: - ps.print(" ; " + f.p[bx].getClass().getName()); - break; - case OP_SETLIST: - if (c == 0) - ps.print(" ; " + ((int) code[++pc])); - else - ps.print(" ; " + ((int) c)); - break; - case OP_VARARG: - ps.print( " ; is_vararg="+ f.is_vararg ); - break; - default: - break; - } - } - - private static int getline(LPrototype f, int pc) { - return pc>0 && f.lineinfo!=null && pc (" + f.code.length + " instructions, " - + f.code.length * 4 + " bytes at " + id(f) + ")\n"); - ps.print(f.numparams + " param, " + f.maxstacksize + " slot, " - + f.upvalues.length + " upvalue, "); - ps.print(f.locvars.length + " local, " + f.k.length - + " constant, " + f.p.length + " function\n"); - } - - static void printConstants(LPrototype f) { - int i, n = f.k.length; - ps.print("constants (" + n + ") for " + id(f) + ":\n"); - for (i = 0; i < n; i++) { - ps.print(" " + (i + 1) + " "); - printValue( ps, f.k[i] ); - ps.print( "\n"); - } - } - - static void printLocals(LPrototype f) { - int i, n = f.locvars.length; - ps.print("locals (" + n + ") for " + id(f) + ":\n"); - for (i = 0; i < n; i++) { - ps.println(" "+i+" "+f.locvars[i].varname+" "+(f.locvars[i].startpc+1)+" "+(f.locvars[i].endpc+1)); - } - } - - static void printUpValues(LPrototype f) { - int i, n = f.upvalues.length; - ps.print("upvalues (" + n + ") for " + id(f) + ":\n"); - for (i = 0; i < n; i++) { - ps.print(" " + i + " " + f.upvalues[i] + "\n"); - } - } - - public void printFunction(LPrototype f, boolean full) { - int i, n = f.p.length; - printHeader(f); - printCode(f); - if (full) { - printConstants(f); - printLocals(f); - printUpValues(f); - } - for (i = 0; i < n; i++) - printFunction(f.p[i], full); - } - - private static void format( String s, int maxcols ) { - int n = s.length(); - if ( n > maxcols ) - ps.print( s.substring(0,maxcols) ); - else { - ps.print( s ); - for ( int i=maxcols-n; --i>=0; ) - ps.print( ' ' ); - } - } - - public static void printState(LuaState state, int base, int top, int max, - LClosure cl, int pc) { - - // print opcode into buffer - PrintStream previous = ps; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ps = new PrintStream( baos ); - printOpCode( cl.p, pc ); - ps.flush(); - ps.close(); - ps = previous; - format( baos.toString(), 40 ); - - ps.print( " b,t=(" ); - format( String.valueOf(base), 3 ); - ps.print( "," ); - format( String.valueOf(top), 3 ); - ps.print( ") " ); - - // print stack - int i=0; - for ( ; i= limit ) { - value = state.stack[ position ]; - state = null; - return true; - } else { - return false; - } - } - - public boolean isClosed() { - return state == null; - } -} diff --git a/src/j2me/org/luaj/lib/j2me/Cldc10IoLib.java b/src/j2me/org/luaj/lib/j2me/Cldc10IoLib.java deleted file mode 100644 index 80048159..00000000 --- a/src/j2me/org/luaj/lib/j2me/Cldc10IoLib.java +++ /dev/null @@ -1,211 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib.j2me; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.microedition.io.Connector; -import javax.microedition.io.StreamConnection; - -import org.luaj.lib.BaseLib; -import org.luaj.lib.IoLib; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; - -/** - * Implementation of the lua io library based on CLDC 1.0 and StreamConnection. - * - * Seek is not supported. - */ -public class Cldc10IoLib extends IoLib { - - public static void install( LTable globals ) { - new Cldc10IoLib().initialize(globals); - } - - public Cldc10IoLib() { - super(); - } - - public Cldc10IoLib(int index) { - super(index); - } - - protected IoLib newInstance(int index) { - return new Cldc10IoLib(index); - } - - protected File wrapStdin() throws IOException { - return new FileImpl(BaseLib.STDIN); - } - - protected File wrapStdout() throws IOException { - return new FileImpl(BaseLib.STDOUT != null? BaseLib.STDOUT: System.out); - } - - protected File openFile( String filename, boolean readMode, boolean appendMode, boolean updateMode, boolean binaryMode ) throws IOException { - String url = "file:///" + filename; - int mode = readMode? Connector.READ: Connector.READ_WRITE; - StreamConnection conn = (StreamConnection) Connector.open( url, mode ); - File f = readMode? - new FileImpl(conn, conn.openInputStream(), null): - new FileImpl(conn, conn.openInputStream(), conn.openOutputStream()); - /* - if ( appendMode ) { - f.seek("end",0); - } else { - if ( ! readMode ) - conn.truncate(0); - } - */ - return f; - } - - private static void notimplemented() throws IOException { - throw new IOException("not implemented"); - } - - protected File openProgram(String prog, String mode) throws IOException { - notimplemented(); - return null; - } - - protected File tmpFile() throws IOException { - notimplemented(); - return null; - } - - private static final class FileImpl implements File { - private final StreamConnection conn; - private final InputStream is; - private final OutputStream os; - private boolean closed = false; - private boolean nobuffer = false; - private int lookahead = -1; - private FileImpl( StreamConnection conn, InputStream is, OutputStream os ) { - this.conn = conn; - this.is = is; - this.os = os; - } - private FileImpl( InputStream i ) { - this( null, i, null ); - } - private FileImpl( OutputStream o ) { - this( null, null, o ); - } - public String toString() { - return "file ("+this.hashCode()+")"; - } - public boolean isstdfile() { - return conn == null; - } - public void close() throws IOException { - closed = true; - if ( conn != null ) { - conn.close(); - } - } - public void flush() throws IOException { - if ( os != null ) - os.flush(); - } - public void write(LString s) throws IOException { - if ( os != null ) - os.write( s.m_bytes, s.m_offset, s.m_length ); - else - notimplemented(); - if ( nobuffer ) - flush(); - } - public boolean isclosed() { - return closed; - } - public int seek(String option, int pos) throws IOException { - /* - if ( conn != null ) { - if ( "set".equals(option) ) { - conn.seek(pos); - return (int) conn.getFilePointer(); - } else if ( "end".equals(option) ) { - conn.seek(conn.length()+1+pos); - return (int) conn.length()+1; - } else { - conn.seek(conn.getFilePointer()+pos); - return (int) conn.getFilePointer(); - } - } - */ - notimplemented(); - return 0; - } - public void setvbuf(String mode, int size) { - nobuffer = "no".equals(mode); - } - - // get length remaining to read - public int remaining() throws IOException { - return -1; - } - - // peek ahead one character - public int peek() throws IOException { - if ( lookahead < 0 ) - lookahead = is.read(); - return lookahead; - } - - // return char if read, -1 if eof, throw IOException on other exception - public int read() throws IOException { - if ( lookahead >= 0 ) { - int c = lookahead; - lookahead = -1; - return c; - } - if ( is != null ) - return is.read(); - notimplemented(); - return 0; - } - - // return number of bytes read if positive, -1 if eof, throws IOException - public int read(byte[] bytes, int offset, int length) throws IOException { - int n,i=0; - if (is!=null) { - if ( length > 0 && lookahead >= 0 ) { - bytes[offset] = (byte) lookahead; - lookahead = -1; - i += 1; - } - for ( ; i 0 ? i : -1 ); - i += n; - } - } else { - notimplemented(); - } - return length; - } - } -} diff --git a/src/j2me/org/luaj/platform/J2meMidp10Cldc10Platform.java b/src/j2me/org/luaj/platform/J2meMidp10Cldc10Platform.java deleted file mode 100644 index c84d3f25..00000000 --- a/src/j2me/org/luaj/platform/J2meMidp10Cldc10Platform.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.luaj.platform; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; - -import javax.microedition.midlet.MIDlet; - -import org.luaj.vm.LNumber; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - -public class J2meMidp10Cldc10Platform extends Platform { - protected MIDlet midlet; - - public String getName() { - return "j2me"; - } - - public J2meMidp10Cldc10Platform(MIDlet midlet) { - this.midlet = midlet; - } - - public Reader createReader(InputStream inputStream) { - return new InputStreamReader(inputStream); - } - - public InputStream openFile(String fileName) { - if (!fileName.startsWith("/")) - fileName = "/" + fileName; - InputStream is = this.getClass().getResourceAsStream(fileName); - return is; - } - public String getProperty(String key) { - return midlet.getAppProperty(key); - } - - protected void installOptionalLibs(LuaState vm) { - vm.installStandardLibs(); - } - - public LNumber mathPow(LNumber base, LNumber exponent) { - return unsupportedMathOp(); - } - - public LNumber mathop(int id, LNumber x, LNumber y) { - return unsupportedMathOp(); - } - - public LNumber mathop(int id, LNumber x) { - return unsupportedMathOp(); - } -} diff --git a/src/j2me/org/luaj/platform/J2meMidp20Cldc11Platform.java b/src/j2me/org/luaj/platform/J2meMidp20Cldc11Platform.java deleted file mode 100644 index d6df7dd6..00000000 --- a/src/j2me/org/luaj/platform/J2meMidp20Cldc11Platform.java +++ /dev/null @@ -1,84 +0,0 @@ -package org.luaj.platform; - -import javax.microedition.midlet.MIDlet; - -import org.luaj.lib.MathLib; -import org.luaj.vm.LDouble; -import org.luaj.vm.LNumber; - -public class J2meMidp20Cldc11Platform extends J2meMidp10Cldc10Platform { - public J2meMidp20Cldc11Platform(MIDlet midlet) { - super(midlet); - } - - public LNumber mathPow(LNumber base, LNumber exp) { - return LDouble.numberOf(dpow(base.toJavaDouble(),exp.toJavaDouble())); - } - - public LNumber mathop(int id, LNumber la, LNumber lb) { - double a = la.toJavaDouble(); - double b = lb.toJavaDouble(); - double z = 0; - switch ( id ) { - default: return unsupportedMathOp(); - //case MathLib.ATAN2: z = - // b>0? Math.atan(a/b): - // b<0? (a>=0? Math.PI-Math.atan(a/-b): -Math.PI-Math.atan(a/-b)): - // (a>0? Math.PI/2: a<0? -Math.PI/2: 0); - // break; - case MathLib.FMOD: z = a - (b * ((int)(a/b))); break; - case MathLib.POW: z = dpow(a, b); break; - } - return LDouble.numberOf(z); - } - - - public LNumber mathop(int id, LNumber lx) { - double x = lx.toJavaDouble(); - double z = 0; - switch ( id ) { - default: return unsupportedMathOp(); - case MathLib.ABS: z = Math.abs(x); break; - //case MathLib.ACOS: z = Math.acos(x); break; - //case MathLib.ASIN: z = Math.asin(x); break; - //case MathLib.ATAN: z = Math.atan(x); break; - case MathLib.COS: z = Math.cos(x); break; - //case MathLib.COSH: z = (Math.exp(x) + Math.exp(-x)) / 2; break; - case MathLib.DEG: z = Math.toDegrees(x); break; - //case MathLib.EXP: z = Math.exp(x); break; - //case MathLib.LOG: z = Math.log(x); break; - //case MathLib.LOG10: z = Math.log10(x); break; - case MathLib.RAD: z = Math.toRadians(x); break; - case MathLib.SIN: z = Math.sin(x); break; - //case MathLib.SINH: z = (Math.exp(x) - Math.exp(-x)) / 2; break; - case MathLib.SQRT: z = Math.sqrt(x); break; - case MathLib.TAN: z = Math.tan(x); break; - //case MathLib.TANH: { - // double e = Math.exp(2*x); - // z = (e-1) / (e+1); - // break; - //} - } - return LDouble.numberOf(z); - } - - public static double dpow(double a, double b) { - if ( b < 0 ) - return 1 / dpow( a, -b ); - double p = 1; - int whole = (int) b; - for ( double v=a; whole > 0; whole>>=1, v*=v ) - if ( (whole & 1) != 0 ) - p *= v; - if ( (b -= whole) > 0 ) { - int frac = (int) (0x10000 * b); - for ( ; (frac&0xffff)!=0; frac<<=1 ) { - a = Math.sqrt(a); - if ( (frac & 0x8000) != 0 ) - p *= a; - } - } - return p; - } - -} diff --git a/src/j2se/lua.java b/src/j2se/lua.java deleted file mode 100644 index dc1bd649..00000000 --- a/src/j2se/lua.java +++ /dev/null @@ -1,211 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import org.luaj.compiler.LuaC; -import org.luaj.lib.DebugLib; -import org.luaj.platform.J2sePlatform; -import org.luaj.vm.LFunction; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - - -/** - * lua command for use in java se environments. - */ -public class lua { - private static final String version = Lua._VERSION + " Copyright (C) 2009 luaj.org"; - - private static final String usage = - "usage: java -cp luaj-j2se.jar lua [options] [script [args]].\n" + - "Available options are:\n" + - " -e stat execute string 'stat'\n" + - " -l name require library 'name'\n" + - " -i enter interactive mode after executing 'script'\n" + - " -v show version information\n" + - " -- stop handling options\n" + - " - execute stdin and stop handling options"; - - private static void usageExit() { - System.out.println(usage); - System.exit(-1); - } - - public static void main( String[] args ) throws IOException { - - // new lua state - Platform.setInstance(new J2sePlatform()); - LuaC.install(); - LuaState vm = Platform.newLuaState(); - DebugLib.install(vm); - - // process args - boolean interactive = (args.length == 0); - boolean versioninfo = false; - boolean processing = true; - try { - // stateful argument processing - for ( int i=0; i= args.length ) - usageExit(); - // input script - defer to last stage - break; - case 'l': - if ( ++i >= args.length ) - usageExit(); - loadLibrary( vm, args[i] ); - break; - case 'i': - interactive = true; - break; - case 'v': - versioninfo = true; - break; - case '-': - if ( args[i].length() > 2 ) - usageExit(); - processing = false; - break; - default: - usageExit(); - break; - } - } - } - - // echo version - if ( versioninfo ) - System.out.println(version); - - // input script processing - processing = true; - for ( int i=0; i "); - System.out.flush(); - String line = reader.readLine(); - if ( line == null ) - return; - processScript( vm, new ByteArrayInputStream(line.getBytes()), "-", null, 0 ); - } - } -} diff --git a/src/j2se/luac.java b/src/j2se/luac.java deleted file mode 100644 index 55afbd83..00000000 --- a/src/j2se/luac.java +++ /dev/null @@ -1,185 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.luaj.compiler.DumpState; -import org.luaj.compiler.LuaC; -import org.luaj.platform.J2sePlatform; -import org.luaj.vm.LPrototype; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; -import org.luaj.vm.Print; - - -/** - * luac command for use in java se environments. - */ -public class luac { - private static final String version = Lua._VERSION + "Copyright (C) 2008 luaj.org"; - - private static final String usage = - "usage: java -cp luaj-j2se.jar luac [options] [filenames].\n" + - "Available options are:\n" + - " - process stdin\n" + - " -l list\n" + - " -o name output to file 'name' (default is \"luac.out\")\n" + - " -p parse only\n" + - " -s strip debug information\n" + - " -e little endian format for numbers\n" + - " -i number format 'n', (n=0,1 or 4, default="+DumpState.NUMBER_FORMAT_DEFAULT+")\n" + - " -v show version information\n" + - " -- stop handling options\n"; - - private static void usageExit() { - System.out.println(usage); - System.exit(-1); - } - - private boolean list = false; - private String output = "luac.out"; - private boolean parseonly = false; - private boolean stripdebug = false; - private boolean littleendian = false; - private int numberformat = DumpState.NUMBER_FORMAT_DEFAULT; - private boolean versioninfo = false; - private boolean processing = true; - - public static void main( String[] args ) throws IOException { - new luac( args ); - } - - private luac( String[] args ) throws IOException { - // new lua state - Platform.setInstance(new J2sePlatform()); - LuaC.install(); - LuaState vm = Platform.newLuaState(); - - // process args - try { - // get stateful args - for ( int i=0; i= args.length ) - usageExit(); - output = args[i]; - break; - case 'p': - parseonly = true; - break; - case 's': - stripdebug = true; - break; - case 'e': - littleendian = true; - break; - case 'i': - if ( args[i].length() <= 2 ) - usageExit(); - numberformat = Integer.parseInt(args[i].substring(2)); - break; - case 'v': - versioninfo = true; - break; - case '-': - if ( args[i].length() > 2 ) - usageExit(); - processing = false; - break; - default: - usageExit(); - break; - } - } - } - - // echo version - if ( versioninfo ) - System.out.println(version); - - // open output file - OutputStream fos = new FileOutputStream( output ); - - // process input files - try { - processing = true; - for ( int i=0; i=0? path.substring(0,i+1): path; - } - - private boolean callFunction( String name ) { - try { - vm.getglobal( name ); - if ( ! vm.isfunction(-1) ) { - vm.pop(1); - return false; - } - else { - vm.pushlvalue( lthis ); - vm.call( 1, 0 ); - return true; - } - } catch ( Throwable t ) { - System.err.println(name+"():"); - t.printStackTrace( System.err ); - return true; - } - } - - public synchronized void start() { - super.start(); - callFunction( "start" ); - } - - public synchronized void stop() { - callFunction( "stop" ); - super.stop(); - } - - public synchronized void destroy() { - callFunction( "destroy" ); - super.destroy(); - } -} diff --git a/src/j2se/org/luaj/lib/j2se/CoerceJavaToLua.java b/src/j2se/org/luaj/lib/j2se/CoerceJavaToLua.java deleted file mode 100644 index 4080ddcc..00000000 --- a/src/j2se/org/luaj/lib/j2se/CoerceJavaToLua.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib.j2se; - -import java.util.HashMap; -import java.util.Map; - -import org.luaj.vm.LBoolean; -import org.luaj.vm.LDouble; -import org.luaj.vm.LInteger; -import org.luaj.vm.LNil; -import org.luaj.vm.LString; -import org.luaj.vm.LValue; - - -public class CoerceJavaToLua { - - public static interface Coercion { - public LValue coerce( Object javaValue ); - }; - - private static Map COERCIONS = new HashMap(); - - static { - Coercion boolCoercion = new Coercion() { - public LValue coerce( Object javaValue ) { - Boolean b = (Boolean) javaValue; - return b.booleanValue()? LBoolean.TRUE: LBoolean.FALSE; - } - } ; - Coercion intCoercion = new Coercion() { - public LValue coerce( Object javaValue ) { - Number n = (Number) javaValue; - return LInteger.valueOf( n.intValue() ); - } - } ; - Coercion charCoercion = new Coercion() { - public LValue coerce( Object javaValue ) { - Character c = (Character) javaValue; - return LInteger.valueOf( c.charValue() ); - } - } ; - Coercion doubleCoercion = new Coercion() { - public LValue coerce( Object javaValue ) { - Number n = (Number) javaValue; - return LDouble.numberOf( n.doubleValue() ); - } - } ; - Coercion stringCoercion = new Coercion() { - public LValue coerce( Object javaValue ) { - return new LString( javaValue.toString() ); - } - } ; - COERCIONS.put( Boolean.class, boolCoercion ); - COERCIONS.put( Byte.class, intCoercion ); - COERCIONS.put( Character.class, charCoercion ); - COERCIONS.put( Short.class, intCoercion ); - COERCIONS.put( Integer.class, intCoercion ); - COERCIONS.put( Float.class, doubleCoercion ); - COERCIONS.put( Double.class, doubleCoercion ); - COERCIONS.put( String.class, stringCoercion ); - } - - public static LValue coerce(Object o) { - if ( o == null ) - return LNil.NIL; - Class clazz = o.getClass(); - Coercion c = (Coercion) COERCIONS.get( clazz ); - if ( c != null ) - return c.coerce( o ); - return LuajavaLib.toUserdata( o, clazz ); - } - -} diff --git a/src/j2se/org/luaj/lib/j2se/CoerceLuaToJava.java b/src/j2se/org/luaj/lib/j2se/CoerceLuaToJava.java deleted file mode 100644 index 9cae61d3..00000000 --- a/src/j2se/org/luaj/lib/j2se/CoerceLuaToJava.java +++ /dev/null @@ -1,283 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.lib.j2se; - -import java.lang.reflect.Array; -import java.util.HashMap; -import java.util.Map; - -import org.luaj.vm.LBoolean; -import org.luaj.vm.LDouble; -import org.luaj.vm.LInteger; -import org.luaj.vm.LNumber; -import org.luaj.vm.LString; -import org.luaj.vm.LTable; -import org.luaj.vm.LUserData; -import org.luaj.vm.LValue; -import org.luaj.vm.LuaErrorException; - - -public class CoerceLuaToJava { - - public static interface Coercion { - public Object coerce( LValue value ); - public int score( LValue value ); - }; - - private static Map COERCIONS = new HashMap(); - private static Coercion OBJECT_COERCION; - - static { - Coercion boolCoercion = new Coercion() { - public Object coerce(LValue value) { - return value.toJavaBoolean()? Boolean.TRUE: Boolean.FALSE; - } - public int score(LValue value) { - if ( value instanceof LBoolean || value.isNil() ) - return 0; - if ( value instanceof LNumber ) - return 1; - return 4; - } - }; - Coercion byteCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Byte( value.toJavaByte() ); - } - public int score(LValue value) { - if ( value instanceof LInteger ) - return 1; - if ( value instanceof LNumber ) - return 2; - return 4; - } - }; - Coercion charCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Character( value.toJavaChar() ); - } - public int score(LValue value) { - if ( value instanceof LInteger ) - return 1; - if ( value instanceof LNumber ) - return 2; - return 4; - } - }; - Coercion shortCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Short( value.toJavaShort() ); - } - public int score(LValue value) { - if ( value instanceof LInteger ) - return 1; - if ( value instanceof LNumber ) - return 2; - return 4; - } - }; - Coercion intCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Integer( value.toJavaInt() ); - } - public int score(LValue value) { - if ( value instanceof LInteger ) - return 0; - if ( value instanceof LNumber ) - return 1; - if ( value instanceof LBoolean || value.isNil() ) - return 2; - return 4; - } - }; - Coercion longCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Long( value.toJavaLong() ); - } - public int score(LValue value) { - if ( value instanceof LInteger ) - return 1; - if ( value instanceof LNumber ) - return 2; - return 4; - } - }; - Coercion floatCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Float( value.toJavaFloat() ); - } - public int score( LValue value ) { - if ( value instanceof LNumber ) - return 1; - if ( value instanceof LBoolean ) - return 2; - return 4; - } - }; - Coercion doubleCoercion = new Coercion() { - public Object coerce(LValue value) { - return new Double( value.toJavaDouble() ); - } - public int score(LValue value) { - if ( value instanceof LDouble ) - return 0; - if ( value instanceof LNumber ) - return 1; - if ( value instanceof LBoolean ) - return 2; - return 4; - } - }; - Coercion stringCoercion = new Coercion() { - public Object coerce(LValue value) { - return value.toJavaString(); - } - public int score(LValue value) { - if ( value instanceof LUserData ) - return 0; - return 1; - } - }; - Coercion objectCoercion = new Coercion() { - public Object coerce(LValue value) { - if ( value instanceof LUserData ) - return ((LUserData)value).m_instance; - if ( value instanceof LString ) - return value.toJavaString(); - if ( value instanceof LInteger ) - return new Integer(value.toJavaInt()); - if ( value instanceof LDouble ) - return new Double(value.toJavaDouble()); - if ( value instanceof LBoolean ) - return Boolean.valueOf(value.toJavaBoolean()); - if ( value.isNil() ) - return null; - return value; - } - public int score(LValue value) { - if ( value instanceof LString ) - return 0; - return 0x10; - } - }; - COERCIONS.put( Boolean.TYPE, boolCoercion ); - COERCIONS.put( Boolean.class, boolCoercion ); - COERCIONS.put( Byte.TYPE, byteCoercion ); - COERCIONS.put( Byte.class, byteCoercion ); - COERCIONS.put( Character.TYPE, charCoercion ); - COERCIONS.put( Character.class, charCoercion ); - COERCIONS.put( Short.TYPE, shortCoercion ); - COERCIONS.put( Short.class, shortCoercion ); - COERCIONS.put( Integer.TYPE, intCoercion ); - COERCIONS.put( Integer.class, intCoercion ); - COERCIONS.put( Long.TYPE, longCoercion ); - COERCIONS.put( Long.class, longCoercion ); - COERCIONS.put( Float.TYPE, floatCoercion ); - COERCIONS.put( Float.class, floatCoercion ); - COERCIONS.put( Double.TYPE, doubleCoercion ); - COERCIONS.put( Double.class, doubleCoercion ); - COERCIONS.put( String.class, stringCoercion ); - COERCIONS.put( Object.class, objectCoercion ); - } - - - /** Score a single parameter, including array handling */ - private static int scoreParam(LValue a, Class c) { - if ( a instanceof LUserData ) { - Object o = ((LUserData) a).m_instance; - if ( c.isAssignableFrom(o.getClass()) ) - return 0; - } - Coercion co = (Coercion) COERCIONS.get( c ); - if ( co != null ) { - return co.score( a ); - } - if ( c.isArray() ) { - Class typ = c.getComponentType(); - if ( a instanceof LTable ) { - return scoreParam( ((LTable)a).get(1), typ ); - } else { - return 0x10 + (scoreParam(a, typ) << 8); - } - } - return 0x1000; - } - - /** Do a conversion */ - public static Object coerceArg(LValue a, Class c) { - if ( a instanceof LUserData ) { - Object o = ((LUserData) a).m_instance; - if ( c.isAssignableFrom(o.getClass()) ) - return o; - } - Coercion co = (Coercion) COERCIONS.get( c ); - if ( co != null ) { - return co.coerce( a ); - } - if ( c.isArray() ) { - boolean istable = (a instanceof LTable); - int n = istable? a.luaLength(): 1; - Class typ = c.getComponentType(); - Object o = Array.newInstance(typ, n); - for ( int i=0; i nargs? 0x4000: 0x8000); - for ( int i=0; i= 0 && index < Array.getLength(instance) ) - vm.pushlvalue( CoerceJavaToLua.coerce( Array.get(instance, index) ) ); - else - vm.pushnil(); - return false; - } - } - final String s = key.toJavaString(); - vm.resettop(); - try { - Field f = clazz.getField(s); - Object o = f.get(instance); - vm.pushlvalue( CoerceJavaToLua.coerce( o ) ); - } catch (NoSuchFieldException nsfe) { - if ( clazz.isArray() && key.equals(LENGTH) ) { - vm.pushinteger( Array.getLength(instance) ); - } else { - vm.pushlvalue( new LMethod(clazz,s) ); - } - } catch (Exception e) { - throw new LuaErrorException(e); - } - return false; - } - }); - mt.put( LValue.TM_NEWINDEX, new LFunction() { - public boolean luaStackCall(LuaState vm) { - Object instance = vm.touserdata(2); - LValue key = vm.topointer(3); - LValue val = vm.topointer(4); - if ( key instanceof LInteger ) { - if ( clazz.isArray() ) { - vm.resettop(); - Object v = CoerceLuaToJava.coerceArg(val, clazz.getComponentType()); - int index = key.toJavaInt()-1; - if ( index >= 0 && index < Array.getLength(instance) ) - Array.set(instance, key.toJavaInt()-1, v); - else - throw new LuaErrorException("array bounds exceeded "+index); - vm.resettop(); - return false; - } - } - String s = key.toJavaString(); - try { - Field f = clazz.getField(s); - Object v = CoerceLuaToJava.coerceArg(val, f.getType()); - f.set(instance,v); - vm.resettop(); - } catch (Exception e) { - throw new LuaErrorException(e); - } - return false; - } - }); - classMetatables.put(clazz, mt); - } - return new LUserData(obj,mt); - } - - private static final class LMethod extends LFunction { - private final Class clazz; - private final String s; - private LMethod(Class clazz, String s) { - this.clazz = clazz; - this.s = s; - } - public String toString() { - return clazz.getName()+"."+s+"()"; - } - public boolean luaStackCall(LuaState vm) { - try { - // find the method - Object instance = vm.touserdata(2); - ParamsList params = new ParamsList( vm ); - Method meth = resolveMethod( clazz, s, params ); - - // coerce the arguments - Object[] args = CoerceLuaToJava.coerceArgs( params.values, meth.getParameterTypes() ); - Object result = meth.invoke( instance, args ); - - // coerce the result - vm.resettop(); - vm.pushlvalue( CoerceJavaToLua.coerce(result) ); - return false; - } catch (Exception e) { - throw new LuaErrorException(e); - } - } - } - - private static Map consCache = - new HashMap(); - - private static Map consIndex = - new HashMap(); - - private static Constructor resolveConstructor(Class clazz, ParamsList params ) { - - // get the cache - Map cache = (Map) consCache.get( clazz ); - if ( cache == null ) - consCache.put( clazz, cache = new HashMap() ); - - // look up in the cache - Constructor c = (Constructor) cache.get( params ); - if ( c != null ) - return c; - - // get index - Map index = (Map) consIndex.get( clazz ); - if ( index == null ) { - consIndex.put( clazz, index = new HashMap() ); - Constructor[] cons = clazz.getConstructors(); - for ( int i=0; i0? args[0]: "/swingapp.lua"); - System.out.println("loading '"+script+"'"); - - // load the file - InputStream is = LuajavaRunner.class.getResourceAsStream( script ); - LPrototype p = LoadState.undump(state, is, script); - - // create closure and execute - LClosure c = p.newClosure( state._G ); - state.doCall(c, new LValue[0]); - - } -} diff --git a/src/sample/org/luaj/sample/SampleClass.java b/src/sample/org/luaj/sample/SampleClass.java deleted file mode 100644 index 1771a67f..00000000 --- a/src/sample/org/luaj/sample/SampleClass.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.sample; - -public class SampleClass { - - public Object o; - public String s; - public String t; - - public SampleClass() { - } - - public SampleClass(String a, String b) { - s = a; - t = b; - } - - public String getS() { - return s; - } - - public void setS(String s) { - this.s = s; - } - - public void setObj(Object o) { - this.o = o; - } - - public Object getObj() { - return o; - } -} diff --git a/src/sample/org/luaj/sample/SampleJ2seMain.java b/src/sample/org/luaj/sample/SampleJ2seMain.java deleted file mode 100644 index a28b3f10..00000000 --- a/src/sample/org/luaj/sample/SampleJ2seMain.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.luaj.sample; -import org.luaj.platform.*; -import org.luaj.vm.*; - -public class SampleJ2seMain { - - public static void main(String[] args) { - String script = (args.length>0? args[0]: "src/test/res/swingapp.lua"); - Platform.setInstance( new J2sePlatform() ); - LuaState vm = Platform.newLuaState(); - // uncomment to install the debug library - // org.luaj.lib.DebugLib.install(vm); - org.luaj.compiler.LuaC.install(); - vm.getglobal( "dofile" ); - vm.pushstring( script ); - vm.call( 1, 0 ); - } -} diff --git a/src/sample/org/luaj/sample/SampleMIDlet.java b/src/sample/org/luaj/sample/SampleMIDlet.java deleted file mode 100644 index cee1ef5d..00000000 --- a/src/sample/org/luaj/sample/SampleMIDlet.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.luaj.sample; - -import javax.microedition.midlet.MIDlet; -import javax.microedition.midlet.MIDletStateChangeException; - -import org.luaj.lib.j2me.Cldc10IoLib; -import org.luaj.platform.J2meMidp20Cldc11Platform; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - -public class SampleMIDlet extends MIDlet { - - // the script will be loaded as a resource - private static final String DEFAULT_SCRIPT = "test1.lua"; - - protected void startApp() throws MIDletStateChangeException { - // get the script as an app property - String script = this.getAppProperty("script"); - if ( script == null ) - script = DEFAULT_SCRIPT; - - // set up the j2me platform. files will be loaded as resources - Platform.setInstance( new J2meMidp20Cldc11Platform(this) ); - LuaState vm = Platform.newLuaState(); - - // extend the basic vm to include the compiler and io packages - org.luaj.compiler.LuaC.install(); - Cldc10IoLib.install(vm._G); - - // run the script - vm.getglobal( "dofile" ); - vm.pushstring( script ); - vm.call( 1, 0 ); - } - - protected void destroyApp(boolean arg0) throws MIDletStateChangeException { - } - - protected void pauseApp() { - } - -} diff --git a/src/sample/org/luaj/sample/SampleUserdataMain.java b/src/sample/org/luaj/sample/SampleUserdataMain.java deleted file mode 100644 index 992b9b11..00000000 --- a/src/sample/org/luaj/sample/SampleUserdataMain.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.luaj.sample; -import org.luaj.lib.j2se.CoerceJavaToLua; -import org.luaj.platform.*; -import org.luaj.vm.*; - -/** - * Program that illustrates how userdata is mapped into lua using - * LuaJava's automated coercion - */ -public class SampleUserdataMain { - - public static class MyData { - public int x = 7; - public String y = "seven"; - public int xx[] = new int[] { 11, 22, 33, }; - public String yy[] = new String[] { "aa", "bb" }; - public int xxx[][] = new int[][] { {444, 555}, {666, 777} } ; - public String yyy[][] = new String[][] { { "ccc", "ddd" }, { "eee", "fff" } }; - public void initScalars( int newx, String newy ) { - x = newx; - y = newy; - } - public void initArrays( int[] newxx, String[] newyy ) { - xx = newxx; - yy = newyy; - } - public void initMatrices( int[][] newxxx, String[][] newyyy ) { - xxx = newxxx; - yyy = newyyy; - } - public int getx() { return x; } - public String gety() { return y; } - public int[] getxx() { return xx; } - public String[] getyy() { return yy; } - public int[][] getxxx() { return xxx; } - public String[][] getyyy() { return yyy; } - } - - public static void main(String[] args) { - Platform.setInstance( new J2sePlatform() ); - LuaState vm = Platform.newLuaState(); - org.luaj.compiler.LuaC.install(); - - // test script - vm.getglobal( "loadstring" ); - vm.pushstring( "local mydata = ...\n" + - "print( 'mydata', mydata )\n" + - "print( 'mydata.x, mydata.y', mydata.x, mydata.y )\n" + - "print( 'mydata:getx()', mydata:getx() )\n" + - "print( 'mydata:getxx()', mydata:getxx()[1], mydata:getxx()[2] )\n" + - "print( 'mydata:getxxx()', mydata:getxxx()[1][1], mydata:getxxx()[1][2] )\n" + - "print( 'mydata:getyyy()', mydata:getyyy()[1][1], mydata:getyyy()[1][2] )\n" + - "mydata:initScalars(3,'pqr')\n" + - "mydata:initArrays({55,66},{'abc','def'})\n" + - "mydata:initMatrices({{44,55},{66}},{{'qq','rr'},{'ss','tt'}})\n" + - "print( 'mydata:getx()', mydata:getx() )\n" + - "print( 'mydata:getxx()', mydata:getxx()[1], mydata:getxx()[2] )\n" + - "print( 'mydata:getxxx()', mydata:getxxx()[1][1], mydata:getxxx()[1][2] )\n" + - "print( 'mydata:getyyy()', mydata:getyyy()[1][1], mydata:getyyy()[1][2] )\n" + - ""); - vm.call( 1, 2 ); - System.out.println("load result: "+vm.tostring(-2)+", "+vm.tostring(-1)); - vm.settop(1); - - // load argument to test script - vm.pushlvalue( CoerceJavaToLua.coerce(new MyData()) ); - vm.call( 1, 0 ); - } -} diff --git a/src/script/META-INF/services/javax.script.ScriptEngineFactory b/src/script/META-INF/services/javax.script.ScriptEngineFactory deleted file mode 100644 index 9c755ea1..00000000 --- a/src/script/META-INF/services/javax.script.ScriptEngineFactory +++ /dev/null @@ -1 +0,0 @@ -org.luaj.script.LuaScriptEngineFactory \ No newline at end of file diff --git a/src/script/org/luaj/jit/JitPrototype.java b/src/script/org/luaj/jit/JitPrototype.java deleted file mode 100644 index 1acb5c38..00000000 --- a/src/script/org/luaj/jit/JitPrototype.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.luaj.jit; - -import org.luaj.vm.LClosure; -import org.luaj.vm.LNil; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LTable; -import org.luaj.vm.LValue; -import org.luaj.vm.LuaState; - -abstract -public class JitPrototype extends LPrototype { - - protected LPrototype p; - - public JitPrototype() { - super(); - } - - protected void unimplemented() { - throw new RuntimeException("unimplemented"); - } - - protected void setLuaPrototype(LPrototype lp) { - this.p = lp; - } - - public LClosure newClosure(LTable env) { - return new JitClosure(this, env); - } - - protected static final class JitClosure extends LClosure { - private final JitPrototype jp; - public JitClosure(JitPrototype jitPrototype, LTable env) { - super( jitPrototype.p, env ); - this.jp = jitPrototype; - } - public boolean luaStackCall(LuaState vm) { - jp.jitCall(vm,env,this); - return false; - } - } - - public abstract void jitCall( LuaState vm, LTable env, JitClosure jcl ); - -} diff --git a/src/script/org/luaj/jit/LuaJit.java b/src/script/org/luaj/jit/LuaJit.java deleted file mode 100644 index 5542b786..00000000 --- a/src/script/org/luaj/jit/LuaJit.java +++ /dev/null @@ -1,718 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2007 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.jit; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import javax.tools.JavaCompiler; -import javax.tools.JavaFileObject; -import javax.tools.StandardJavaFileManager; -import javax.tools.StandardLocation; -import javax.tools.ToolProvider; -import javax.tools.JavaCompiler.CompilationTask; - -import org.luaj.compiler.LuaC; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LValue; -import org.luaj.vm.LoadState; -import org.luaj.vm.Lua; -import org.luaj.vm.LuaState; -import org.luaj.vm.Print; -import org.luaj.vm.LoadState.LuaCompiler; - -public class LuaJit extends Lua implements LuaCompiler { - - private static LuaC luac; - - public static void install() { - luac = new LuaC(); - LoadState.compiler = new LuaJit(); - } - - private static int filenum = 0; - - private static synchronized String filename() { - return "LuaJit"+(filenum++); - } - - public LPrototype compile(int firstByte, InputStream stream, String name) throws IOException { - return jitCompile( luac.compile(firstByte, stream, name) ); - } - - public static LPrototype jitCompile( LPrototype p ) { - try { - final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - if (compiler == null) { - System.err.println("no java compiler"); - return p; - } - - // write the file - String name = filename(); - new File("jit").mkdirs(); - File source = new File("jit/"+name+JavaFileObject.Kind.SOURCE.extension); - PrintStream ps = new PrintStream(new FileOutputStream(source)); - writeSource(ps, name, p); - ps.close(); - - // set up output location - Iterable dest = Arrays.asList(new File[] { new File("bin") }); - StandardJavaFileManager fm = compiler.getStandardFileManager( null, null, null); - fm.setLocation(StandardLocation.CLASS_OUTPUT, dest); - - // compile the file - Iterable compilationUnits = fm.getJavaFileObjects(source); - CompilationTask task = compiler.getTask(null, fm, null, null, null, compilationUnits); - boolean success = task.call(); - - // instantiate, config and return - if (success) { - // compile sub-prototypes - if ( p.p != null ) { - for ( int i=0, n=p.p.length; i TESTS = new HashSet(); - static { - TESTS.add( OP_TEST ); - TESTS.add( OP_EQ ); - TESTS.add( OP_LT ); - TESTS.add( OP_LE ); - TESTS.add( OP_TESTSET ); - } - - private static boolean istest(int instr) { - int opcode = Lua.GET_OPCODE(instr); - return TESTS.contains(opcode); - } - - private static boolean isjump(int instr) { - if ( OP_JMP != Lua.GET_OPCODE(instr) ) - return false; - return true; - } - - private static boolean isbackwardjump(int instr) { - return isjump(instr) && (LuaState.GETARG_sBx(instr) < 0); - } - - private static boolean isforwardjump(int instr) { - return isjump(instr) && (LuaState.GETARG_sBx(instr) > 0); - } - - private static boolean isloopbottom(int instr) { - return isbackwardjump(instr) || OP_FORLOOP == Lua.GET_OPCODE(instr); - } - - private static String append( String s, String t ) { - return (s==null? t: t==null? s: s+t); - } - - private static void assertTrue(boolean b) { - if ( ! b ) - throw new RuntimeException("assert failed"); - } - - private static String[] extractControlFlow( int[] code ) { - int n = code.length; - String[] s = new String[n]; - - for ( int pc=0; pc 0 ) { - ps.print( "\tprivate LValue k0" ) ; - for (int ik=1; ik> POS_OP) & MAX_OP; - a = (i >> POS_A) & MAXARG_A; - - switch (o) { - default: - ps.println( "\t\tunimplemented();"); - break; - case LuaState.OP_MOVE: { - b = LuaState.GETARG_B(i); - ps.println( "\t\ts"+a+" = s"+b+";" ); - continue; - } - case LuaState.OP_LOADK: { - b = LuaState.GETARG_Bx(i); - ps.println( "\t\ts"+a+" = k"+b+";" ); - continue; - } - case LuaState.OP_LOADBOOL: { -// b = LuaState.GETARG_B(i); -// c = LuaState.GETARG_C(i); -// this.stack[base + a] = (b != 0 ? LBoolean.TRUE : LBoolean.FALSE); -// if (c != 0) -// ci.pc++; // skip next instruction (if C) -// continue; - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - ps.println( "\t\ts"+a+" = LBoolean."+(b!=0? "TRUE": "FALSE")+";" ); - if ( c != 0 ) - throw new java.lang.UnsupportedOperationException("can't jit compile LOADBOOL with c != 0"); - break; - } - case LuaState.OP_LOADNIL: { - b = LuaState.GETARG_B(i); - ps.print("\t\t"); - for ( int j=a; j<=b; j++ ) - ps.print("s"+j+"="); - ps.println("LNil.NIL;"); - break; - } - case LuaState.OP_GETUPVAL: { - //b = LuaState.GETARG_B(i); - //this.stack[base + a] = cl.upVals[b].getValue(); - //continue; - b = LuaState.GETARG_B(i); - ps.println("\t\t\ts"+a+" = jcl.upVals["+b+"].getValue();"); - break; - } - case LuaState.OP_GETGLOBAL: { - b = LuaState.GETARG_Bx(i); - ps.println("\t\ts"+a+" = vm.luaV_gettable(env, k"+b+");"); - break; - } - case LuaState.OP_GETTABLE: { - b = GETARG_B(i); - cs = GETARG_RKC_jit(i); - ps.println("\t\ts"+a+" = vm.luaV_gettable(s"+b+", "+cs+");"); - break; - } - case LuaState.OP_SETGLOBAL: { - b = LuaState.GETARG_Bx(i); - ps.println("\t\tvm.luaV_settable(env, k"+b+", s"+a+");"); - break; - } - case LuaState.OP_SETUPVAL: { - b = LuaState.GETARG_B(i); - ps.println("\t\t\tjcl.upVals["+b+"].setValue(s"+a+");"); - break; - } - case LuaState.OP_SETTABLE: { - bs = GETARG_RKB_jit(i); - cs = GETARG_RKC_jit(i); - ps.println("\t\tvm.luaV_settable(s"+a+", "+bs+", "+cs+");"); - break; - } - case LuaState.OP_NEWTABLE: { - b = GETARG_B(i); - c = GETARG_C(i); - ps.println("\t\ts"+a+" = new LTable("+b+","+c+");"); - break; - } - case LuaState.OP_SELF: { - bs = GETARG_RKB_jit(i); - cs = GETARG_RKC_jit(i); - ps.println("\t\ts"+a+" = vm.luaV_gettable((s"+(a+1)+"="+bs+"), "+cs+");"); - break; - } - case LuaState.OP_ADD: - case LuaState.OP_SUB: - case LuaState.OP_MUL: - case LuaState.OP_DIV: - case LuaState.OP_MOD: - case LuaState.OP_POW: { - bs = GETARG_RKB_jit(i); - cs = GETARG_RKC_jit(i); - ps.println("\t\ts"+a+" = "+cs+".luaBinOpUnknown("+o+","+bs+");"); - break; - } - case LuaState.OP_UNM: { - bs = GETARG_RKB_jit(i); - ps.println("\t\ts"+a+" = "+bs+".luaUnaryMinus();"); - } - case LuaState.OP_NOT: { - bs = GETARG_RKB_jit(i); - ps.println("\t\ts"+a+" = ("+bs+".toJavaBoolean()? LBoolean.TRUE: LBoolean.FALSE);"); - break; - } - case LuaState.OP_LEN: { - bs = GETARG_RKB_jit(i); - ps.println("\t\ts"+a+" = LInteger.valueOf("+bs+".luaLength());"); - } - case LuaState.OP_CONCAT: { - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - ps.println("\t\tbaos = new ByteArrayOutputStream();"); - for (int j = b; j <= c; j++) - ps.println("\t\ts"+j+".luaConcatTo( baos );"); - ps.println("\t\ts"+a+" = new LString( baos.toByteArray() );"); - ps.println("\t\tbaos = null;"); - break; - } - case LuaState.OP_JMP: { - break; - } - case LuaState.OP_EQ: - case LuaState.OP_LT: - case LuaState.OP_LE: { - bs = GETARG_RKB_jit(i); - cs = GETARG_RKC_jit(i); - ps.println( "\t\tif ( "+(a==0?"!":"")+" "+cs+".luaBinCmpUnknown("+o+", "+bs+") )" ); - break; - } - case LuaState.OP_TEST: { - c = LuaState.GETARG_C(i); - ps.println( "\t\tif ( "+(c!=0?"!":"")+" s"+a+".toJavaBoolean() )" ); - break; - } - case LuaState.OP_TESTSET: { -// rkb = GETARG_RKB(k, i); -// c = LuaState.GETARG_C(i); -// if (rkb.toJavaBoolean() != (c != 0)) -// ci.pc++; -// else -// this.stack[base + a] = rkb; -// continue; - bs = GETARG_RKB_jit(i); - c = LuaState.GETARG_C(i); - ps.println( "\t\tif ( "+(c!=0?"!":"")+" "+bs+".toJavaBoolean() )" ); - ps.println( "\t\t\ts"+a+" = "+bs+";" ); - ps.println( "\t\telse" ); - break; - } - case LuaState.OP_CALL: { - // - //// ra is base of new call frame - //this.base += a; - // - //// number of args - //b = LuaState.GETARG_B(i); - //if (b != 0) // else use previous instruction set top - // top = base + b; - // - //// number of return values we need - //c = LuaState.GETARG_C(i); - // - //// make or set up the call - //this.nresults = c - 1; - //if (this.stack[base].luaStackCall(this)) - // return; - // - //// adjustTop only for case when call was completed - //// and number of args > 0. If call completed but - //// c == 0, leave top to point to end of results - //if (c > 0) - // adjustTop(base + c - 1); - // - //// restore base - //base = ci.base; - // - //continue; - - b = LuaState.GETARG_B(i); - c = LuaState.GETARG_C(i); - - // copy call to vm stack - ps.println( "\t\tvm.stack[base+"+a+"] = s"+a+";" ); - - // number of args - if (b > 0) { // else use previous instruction set top - for ( int j=1; j 0 ) - for ( int j=0; j 0. If call completed but - // c == 0, leave top to point to end of results - if (this.nresults >= 0) - adjustTop(base + nresults); - - // force restore of base, etc. - return; - } - */ - case LuaState.OP_RETURN: { - //// number of return vals to return - //b = LuaState.GETARG_B(i) - 1; - //if (b == -1) - // b = top - (base + a); - // - //// close open upvals - //closeUpVals( base ); - // - //// number to copy down - //System.arraycopy(stack, base + a, stack, ci.resultbase, b); - //top = ci.resultbase + b; - // - //// adjust results to what caller expected - //if (ci.nresults >= 0) - // adjustTop(ci.resultbase + ci.nresults); - // - //// pop the call stack - //--cc; - // - //// force a reload of the calling context - //return; - // number of return vals to return - if ( Lua.GET_OPCODE(code[pc-1]) == Lua.OP_RETURN ) - break; - - if ( p.is_vararg != 0 ) - ps.println( "\t\tbase -= nvarargs;" ); - else - ps.println( "\t\tbase -= 1;" ); - - b = LuaState.GETARG_B(i); - if (b > 0) { - for ( int j=1; j toMerge) { - for ( Iterator it=toMerge.entrySet().iterator(); it.hasNext(); ) { - Map.Entry e = (Map.Entry) it.next(); - put( e.getKey(), e.getValue() ); - } - } - public Object remove(Object javakey) { - LValue key = toLua(javakey); - Object result = toJava(env.get(key)); - env.put(key, LNil.NIL); - return result; - } - public boolean containsValue(Object value) { - throw new java.lang.UnsupportedOperationException( - "containsValue() not supported for LuaBindings"); - } - public Set> entrySet() { - throw new java.lang.UnsupportedOperationException( - "entrySet() not supported for LuaBindings"); - } - public boolean isEmpty() { - throw new java.lang.UnsupportedOperationException( - "isEmpty() not supported for LuaBindings"); - } - public Set keySet() { - throw new java.lang.UnsupportedOperationException( - "keySet() not supported for LuaBindings"); - } - public int size() { - throw new java.lang.UnsupportedOperationException( - "size() not supported for LuaBindings"); - } - public Collection values() { - throw new java.lang.UnsupportedOperationException( - "values() not supported for LuaBindings"); - } - } - - // ------ convert char stream to byte stream for lua compiler ----- - - private final class Utf8Encoder extends InputStream { - private final Reader r; - private final int[] buf = new int[2]; - private int n; - - private Utf8Encoder(Reader r) { - this.r = r; - } - - public int read() throws IOException { - if ( n > 0 ) - return buf[--n]; - int c = r.read(); - if ( c < 0x80 ) - return c; - n = 0; - if ( c < 0x800 ) { - buf[n++] = (0x80 | ( c & 0x3f)); - return (0xC0 | ((c>>6) & 0x1f)); - } else { - buf[n++] = (0x80 | ( c & 0x3f)); - buf[n++] = (0x80 | ((c>>6) & 0x3f)); - return (0xE0 | ((c>>12) & 0x0f)); - } - } - } -} diff --git a/src/script/org/luaj/script/LuaScriptEngineFactory.java b/src/script/org/luaj/script/LuaScriptEngineFactory.java deleted file mode 100644 index edda67e7..00000000 --- a/src/script/org/luaj/script/LuaScriptEngineFactory.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.script; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; - -/** - * - * @author jim_roseborough - */ -public class LuaScriptEngineFactory implements ScriptEngineFactory { - - private static final String FILEEXT = ".lua"; - - private static final String [] MIMETYPES = { - "text/plain", - "text/lua", - "application/lua" - }; - - private static final String [] NAMES = { - "lua", - "luaj", - }; - - private ScriptEngine myScriptEngine; - private List extensions; - private List mimeTypes; - private List names; - - public LuaScriptEngineFactory() { - myScriptEngine = new LuaScriptEngine(); - extensions = Collections.nCopies(1, FILEEXT); - mimeTypes = Arrays.asList(MIMETYPES); - names = Arrays.asList(NAMES); - } - - public String getEngineName() { - return getScriptEngine().get(ScriptEngine.ENGINE).toString(); - } - - public String getEngineVersion() { - return getScriptEngine().get(ScriptEngine.ENGINE_VERSION).toString(); - } - - public List getExtensions() { - return extensions; - } - - public List getMimeTypes() { - return mimeTypes; - } - - public List getNames() { - return names; - } - - public String getLanguageName() { - return getScriptEngine().get(ScriptEngine.LANGUAGE).toString(); - } - - public String getLanguageVersion() { - return getScriptEngine().get(ScriptEngine.LANGUAGE_VERSION).toString(); - } - - public Object getParameter(String key) { - return getScriptEngine().get(key).toString(); - } - - public String getMethodCallSyntax(String obj, String m, String... args) { - StringBuffer sb = new StringBuffer(); - sb.append(obj + ":" + m + "("); - int len = args.length; - for (int i = 0; i < len; i++) { - if (i > 0) { - sb.append(','); - } - sb.append(args[i]); - } - sb.append(")"); - return sb.toString(); - } - - public String getOutputStatement(String toDisplay) { - return "print(" + toDisplay + ")"; - } - - public String getProgram(String ... statements) { - StringBuffer sb = new StringBuffer(); - int len = statements.length; - for (int i = 0; i < len; i++) { - if (i > 0) { - sb.append('\n'); - } - sb.append(statements[i]); - } - return sb.toString(); - } - - public ScriptEngine getScriptEngine() { - return myScriptEngine; - } -} diff --git a/src/script/org/luaj/script/ScriptEngineSample.java b/src/script/org/luaj/script/ScriptEngineSample.java deleted file mode 100644 index b3de44a1..00000000 --- a/src/script/org/luaj/script/ScriptEngineSample.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2008 LuaJ. All rights reserved. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -******************************************************************************/ -package org.luaj.script; - -import javax.script.Bindings; -import javax.script.Compilable; -import javax.script.CompiledScript; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; - -public class ScriptEngineSample { - - public static void main(String [] args) { - ScriptEngineManager sem = new ScriptEngineManager(); - ScriptEngine e = sem.getEngineByExtension(".lua"); - ScriptEngineFactory f = e.getFactory(); - System.out.println( "Engine name: " +f.getEngineName() ); - System.out.println( "Engine Version: " +f.getEngineVersion() ); - System.out.println( "LanguageName: " +f.getLanguageName() ); - System.out.println( "Language Version: " +f.getLanguageVersion() ); - String statement = f.getOutputStatement("\"hello, world\""); - System.out.println(statement); - try { - e.eval(statement); - - e.put("x", 25); - e.eval("y = math.sqrt(x)"); - System.out.println( "y="+e.get("y") ); - - e.put("x", 2); - e.eval("y = math.sqrt(x)"); - System.out.println( "y="+e.get("y") ); - - CompiledScript cs = ((Compilable)e).compile("y = math.sqrt(x); return y"); - Bindings b = e.createBindings(); - b.put("x", 3); - System.out.println( "eval: "+cs.eval(b) ); - System.out.println( "y="+b.get("y") ); - - e.eval("\n\nbogus example\n\n"); - } catch (ScriptException ex) { - ex.printStackTrace(); - } - } - -} diff --git a/src/test/java/org/luaj/jit/LuaJitBasicTest.java b/src/test/java/org/luaj/jit/LuaJitBasicTest.java deleted file mode 100644 index 2b72dbdb..00000000 --- a/src/test/java/org/luaj/jit/LuaJitBasicTest.java +++ /dev/null @@ -1,154 +0,0 @@ -package org.luaj.jit; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import junit.framework.TestCase; - -import org.luaj.compiler.LuaC; -import org.luaj.lib.BaseLib; -import org.luaj.platform.J2sePlatform; -import org.luaj.vm.LClosure; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - -/** - * Simple test cases for lua jit basic functional test - */ -public class LuaJitBasicTest extends TestCase { - - static { - Platform.setInstance(new J2sePlatform()); - LuaC.install(); - } - - public void testPrintHelloWorld() throws IOException { - stringTest( "print( 'hello, world' )" ); - } - - public void testArgPassing() throws IOException { - stringTest( - "local function f(a,b)\n" + - " print('a',a,'b',b)\n" + - " return 'c','d'\n" + - "end\n" + - "print( 'f1', f(123) )\n" + - "print( 'f2', f(456,789) )\n" + - "print( 'f3', f(12,34,56) )\n" ); - } - - public void testForInDoEnd() throws IOException { - stringTest( - "local t = {abc=123,def=456}\n" + - "for k,v in pairs(t) do\n" + - " print( 'k,v', k, v )\n" + - "end"); - } - - public void testForIEqualsDoEnd() throws IOException { - stringTest( - "print 'starting'\n" + - "for i=1,5,2 do\n" + - " print( 'i', i )\n" + - "end"); - } - - public void testRepeatUntil() throws IOException { - stringTest( - "local i=7\n" + - "repeat\n"+ - " print(i)\n"+ - "until i\n"); - } - - public void testWhileDoEnd() throws IOException { - stringTest( - "local i=4\n" + - "while i>0 do\n"+ - " print( i )\n"+ - " i = i-1\n"+ - "end\n"); - } - - public void testForIEqualsDoBreakEnd() throws IOException { - stringTest( - "print 'starting'\n" + - "for i=1,5,2 do\n" + - " print( 'i', i )\n" + - " break\n" + - "end"); - } - - public void testRepeatUntilBreak() throws IOException { - stringTest( - "local i=7\n" + - "repeat\n"+ - " print(i)\n"+ - " break\n"+ - "until i\n"); - } - - public void testWhileDoBreak() throws IOException { - stringTest( - "local i=4\n" + - "while i>0 do\n"+ - " print( i )\n"+ - " i = i-1\n"+ - " break\n"+ - "end\n"); - } - - public void testIfThenEnd() throws IOException { - stringTest( - "if a then\n" + - " print(1)\n" + - "end\n" + - "print(2)\n" ); - } - - public void testIfThenElseEnd() throws IOException { - stringTest( - "if a then\n" + - " print(1)\n" + - "else\n" + - " print(2)\n" + - "end\n" + - "print(3)\n" ); - } - - public void testIfThenElseifElseEnd() throws IOException { - stringTest( - "if a then\n" + - " print(1)\n" + - "elseif b then \n" + - " print(2)\n" + - "else\n" + - " print(3)\n" + - "end\n" + - "print(4)\n" ); - } - - private void stringTest(String program) throws IOException { - InputStream is = new ByteArrayInputStream(program.getBytes()); - LPrototype p = LuaC.compile(is, "program"); - String expected = run( p ); - LPrototype q = LuaJit.jitCompile( p ); - assertTrue(p!=q); - String actual = run( q ); - assertEquals( expected, actual ); - } - - private static String run(LPrototype p) { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - BaseLib.redirectOutput(outputStream); - LuaState vm = Platform.newLuaState(); - LClosure c = p.newClosure(vm._G); - vm.pushlvalue(c); - vm.call(0, 0); - return outputStream.toString(); - } - -} diff --git a/src/test/java/org/luaj/jit/LuaJitPerfTest.java b/src/test/java/org/luaj/jit/LuaJitPerfTest.java deleted file mode 100644 index 5df2faf8..00000000 --- a/src/test/java/org/luaj/jit/LuaJitPerfTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.luaj.jit; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -import junit.framework.TestCase; - -import org.luaj.compiler.LuaC; -import org.luaj.lib.BaseLib; -import org.luaj.platform.J2sePlatform; -import org.luaj.vm.LClosure; -import org.luaj.vm.LPrototype; -import org.luaj.vm.LuaState; -import org.luaj.vm.Platform; - -public class LuaJitPerfTest extends TestCase { - - static { - Platform.setInstance(new J2sePlatform()); - LuaC.install(); - } -// -// public void testFannkuch() throws IOException { -// timedFileTest( "fannkuch.lua" ); -// } -// -// public void testMandelbrot() throws IOException { -// timedFileTest( "mandelbrot.lua" ); -// } - - public void testNbody() throws IOException { - timedFileTest( "nbody.lua" ); - } -// -// public void testForLoop() throws IOException { -// timedTest( "for loop", -// "local sum=0\n" + -// "for i=1,10000,1 do\n" + -// " sum = sum + i\n" + -// "end"); -// } -// - - private void timedFileTest(String filename) throws IOException { - File file = new File("src/test/perf/"+filename); - int len = (int) file.length(); - byte[] b = new byte[len]; - DataInputStream dis = new DataInputStream( new FileInputStream( file ) ); - dis.readFully(b); - dis.close(); - timedTest( filename, new String(b) ); - - } - - private void timedTest(String testName, String script) throws IOException { - System.out.println("---- "+testName+" ----"); - InputStream is = new ByteArrayInputStream(script.getBytes()); - LPrototype p = LuaC.compile(is, "script"); - int plain = timeTrial( "plain", p ); - LPrototype q = LuaJit.jitCompile( p ); - assertTrue(p!=q); - int jit = timeTrial( "jit", q ); - System.out.println("plain="+plain+" jit="+jit+" ratio="+(double)jit/(double)plain); - assertTrue( "jit faster than plain", jit > plain ); - } - - private static int timeTrial(String type, LPrototype p) { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - BaseLib.redirectOutput(outputStream); - LuaState vm = Platform.newLuaState(); - LClosure c = p.newClosure(vm._G); - int globalCount = 0; - for ( int i=0; i<5; i++ ) { - int localCount = 0; - long t1 = System.currentTimeMillis() + 1000; - while ( t1 > System.currentTimeMillis() ) { - vm.pushlvalue(c); - vm.call(0, 0); - localCount++; - } - System.out.println(type+": "+(localCount)); - System.out.flush(); - globalCount += localCount; - } - return globalCount; - } -} diff --git a/src/test/java/org/luaj/jit/LuaJitTest.java b/src/test/java/org/luaj/jit/LuaJitTest.java deleted file mode 100644 index 9fbd1915..00000000 --- a/src/test/java/org/luaj/jit/LuaJitTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.luaj.jit; - -import java.io.IOException; - -import org.luaj.jit.LuaJit; -import org.luaj.vm.LPrototype; -import org.luaj.vm.CompatibiltyTest; -import org.luaj.vm.LuaState; - -/** - * Suite of standard tests, but using the LuaJit compiler - * for all loaded prototypes. - */ -public class LuaJitTest extends CompatibiltyTest { - - protected LPrototype loadScript( LuaState state, String name ) throws IOException { - LPrototype p = super.loadScript(state, name); - return LuaJit.jitCompile(p); - } - -} diff --git a/src/test/res/autoload.lua b/src/test/res/autoload.lua deleted file mode 100644 index 341c939a..00000000 --- a/src/test/res/autoload.lua +++ /dev/null @@ -1,15 +0,0 @@ --- Clear out builtin math package -math = nil - -local function autoload(table, key) - local pkg = require(key) - table[key] = pkg - return pkg -end - -setmetatable(_G, { __index = autoload } ) - --- local result = math.sqrt(9.0) --- print("x=", result) -print("square root of 9.0 is ", math.sqrt(9.0)) -print("square root of 4.0 is ", math.sqrt(4.0)) diff --git a/src/test/res/baselib.lua b/src/test/res/baselib.lua deleted file mode 100644 index f68e572b..00000000 --- a/src/test/res/baselib.lua +++ /dev/null @@ -1,280 +0,0 @@ --- unit tests for functions in BaseLib.java -package.path = "?.lua;src/test/res/?.lua" -require 'ids' - --- wrap pcall to return one result --- error message are tested elsewhere -local pc = pcall -local pcall = function(...) - local s,e = pc(...) - if s then return e end - return false, type(e) -end - --- print -print() -print(11) -print("abc",123,nil,"pqr") - --- assert -print( 'assert(true)', assert(true) ) -print( 'pcall(assert,true)', pcall(assert,true) ) -print( 'pcall(assert,false)', pcall(assert,false) ) -print( 'pcall(assert,nil)', pcall(assert,nil) ) -print( 'pcall(assert,true,"msg")', pcall(assert,true,"msg") ) -print( 'pcall(assert,false,"msg")', pcall(assert,false,"msg") ) -print( 'pcall(assert,nil,"msg")', pcall(assert,nil,"msg") ) -print( 'pcall(assert,false,"msg","msg2")', pcall(assert,false,"msg","msg2") ) - --- collectgarbage (not supported) -print( 'collectgarbage("count")', type(collectgarbage("count"))) -print( 'collectgarbage("collect")', type(collectgarbage("collect"))) -print( 'collectgarbage("count")', type(collectgarbage("count"))) - --- dofile (not supported) --- ipairs -print( 'pcall(ipairs)', pcall(ipairs) ) -print( 'pcall(ipairs,nil)', pcall(ipairs,nil) ) -print( 'pcall(ipairs,"a")', pcall(ipairs,"a") ) -print( 'pcall(ipairs,1)', pcall(ipairs,1) ) -for k,v in ipairs({}) do print('ipairs1',k,v)end -for k,v in ipairs({'one','two'}) do print('ipairs2',k,v)end -for k,v in ipairs({aa='aaa',bb='bbb'}) do print('ipairs3',k,v)end -for k,v in ipairs({aa='aaa',bb='bbb','one','two'}) do print('ipairs4',k,v)end -for k,v in ipairs({[30]='30',[20]='20'}) do print('ipairs5',k,v)end - --- load --- loadfile --- loadstring -local lst = "print(3+4); return 8" -local chunk, err = loadstring( lst ) -print( 'loadstring("'..lst..'")', id(chunk), err ) -print( 'loadstring("'..lst..'")()', chunk() ) - --- pairs -print( 'pcall(pairs)', pcall(pairs) ) -print( 'pcall(pairs,nil)', pcall(pairs,nil) ) -print( 'pcall(pairs,"a")', pcall(pairs,"a") ) -print( 'pcall(pairs,1)', pcall(pairs,1) ) -for k,v in pairs({}) do print('pairs1',k,v)end -for k,v in pairs({'one','two'}) do print('pairs2',k,v)end -for k,v in pairs({aa='aaa',bb='bbb'}) do print('pairs3',k,v)end -for k,v in pairs({aa='aaa',bb='bbb','one','two'}) do print('pairs4',k,v)end -for k,v in pairs({[20]='30',[30]='20'}) do print('pairs5',k,v)end - --- _G -print( '_G["abc"] (before)', _G["abc"] ) -abc='def' -print( '_G["abc"] (after)', _G["abc"] ) - --- type -print( 'type(nil)', type(nil) ) -print( 'type("a")', type("a") ) -print( 'type(1)', type(1) ) -print( 'type(1.5)', type(1.5) ) -print( 'type(function() end)', type(function() end) ) -print( 'type({})', type({}) ) -print( 'type(true)', type(true) ) -print( 'type(false)', type(false) ) -print( 'pcall(type,type)', pcall(type,type) ) -print( 'pcall(type)', pcall(type) ) -print( '(function() return pcall(type) end)()', (function() return pcall(type) end)() ) -local function la() return pcall(type) end -print( 'la()', la() ) -function ga() return pcall(type) end -print( 'ga()', ga() ) - --- getfenv, setfenv: tested in setfenv.lua --- getmetatable, setmetatable -ta = { aa1="aaa1", aa2="aaa2" } -tb = { bb1="bbb1", bb2="bbb2" } -print( 'getmetatable(ta)', getmetatable(ta) ) -print( 'getmetatable(tb)', getmetatable(tb) ) -print( 'setmetatable(ta),{cc1="ccc1"}', type( setmetatable(ta,{cc1="ccc1"}) ) ) -print( 'setmetatable(tb),{dd1="ddd1"}', type( setmetatable(tb,{dd1="ddd1"}) ) ) -print( 'getmetatable(ta)["cc1"]', getmetatable(ta)["cc1"] ) -print( 'getmetatable(tb)["dd1"]', getmetatable(tb)["dd1"] ) -print( 'getmetatable(1)', getmetatable(1) ) -print( 'pcall(setmetatable,1)', pcall(setmetatable,1) ) -print( 'pcall(setmetatable,nil)', pcall(setmetatable,nil) ) -print( 'pcall(setmetatable,"ABC")', pcall(setmetatable,"ABC") ) -print( 'pcall(setmetatable,function() end)', pcall(setmetatable,function() end) ) - - --- rawget,rawset -local mt = {aa="aaa", bb="bbb"} -mt.__index = mt -mt.__newindex = mt -local s = {cc="ccc", dd="ddd", } -local t = {cc="ccc", dd="ddd"} -setmetatable(t,mt) -print( 'pcall(rawget)', pcall(rawget)) -print( 'pcall(rawget,"a")', pcall(rawget,"a")) -print( 'pcall(rawget,s)', pcall(rawget,s)) -print( 'pcall(rawget,t)', pcall(rawget,t)) - -function printtables() - function printtable(name,t) - print( ' '..name, t["aa"], t["bb"], t["cc"], t["dd"], t["ee"], t["ff"], t["gg"] ) - print( ' '..name, - rawget(t,"aa"), - rawget(t,"bb"), - rawget(t,"cc"), - rawget(t,"dd"), - rawget(t,"ee"), - rawget(t,"ff"), - rawget(t,"gg") ) - end - printtable( 's', s ) - printtable( 't', t ) - printtable( 'mt', mt ) -end -printtables() -print( 'pcall(rawset,s,"aa","www")', id(rawset(s,"aa","www"))) -printtables() -print( 'pcall(rawset,s,"cc","xxx")', id(rawset(s,"cc","xxx"))) -printtables() -print( 'pcall(rawset,t,"bb","yyy")', id(rawset(t,"aa","yyy"))) -printtables() -print( 'pcall(rawset,t,"dd","zzz")', id(rawset(s,"dd","zzz"))) -printtables() - -printtables() -print( 's["ee"]="ppp"' ); s["ee"]="ppp" -printtables() -print( 's["cc"]="qqq"' ); s["cc"]="qqq" -printtables() -print( 's["bb"]="rrr"' ); t["bb"]="rrr" -printtables() -print( 's["dd"]="sss"' ); t["dd"]="sss" -printtables() -print( 's["gg"]="ttt"' ); mt["gg"]="ttt" -printtables() - - --- select -print( 'pcall(select)', pcall(select) ) -print( 'select(1,11,22,33,44,55)', select(1,11,22,33,44,55) ) -print( 'select(2,11,22,33,44,55)', select(2,11,22,33,44,55) ) -print( 'select(3,11,22,33,44,55)', select(3,11,22,33,44,55) ) -print( 'select(4,11,22,33,44,55)', select(4,11,22,33,44,55) ) -print( 'pcall(select,5,11,22,33,44,55)', pcall(select,5,11,22,33,44,55) ) -print( 'pcall(select,6,11,22,33,44,55)', pcall(select,6,11,22,33,44,55) ) -print( 'pcall(select,7,11,22,33,44,55)', pcall(select,7,11,22,33,44,55) ) -print( 'pcall(select,0,11,22,33,44,55)', pcall(select,0,11,22,33,44,55) ) -print( 'pcall(select,-1,11,22,33,44,55)', pcall(select,-1,11,22,33,44,55) ) -print( 'pcall(select,-2,11,22,33,44,55)', pcall(select,-2,11,22,33,44,55) ) -print( 'pcall(select,-4,11,22,33,44,55)', pcall(select,-4,11,22,33,44,55) ) -print( 'pcall(select,-5,11,22,33,44,55)', pcall(select,-5,11,22,33,44,55) ) -print( 'pcall(select,-6,11,22,33,44,55)', pcall(select,-6,11,22,33,44,55) ) -print( 'pcall(select,1)', pcall(select,1) ) -print( 'pcall(select,select)', pcall(select,select) ) -print( 'pcall(select,{})', pcall(select,{}) ) -print( 'pcall(select,"2",11,22,33)', pcall(select,"2",11,22,33) ) -print( 'pcall(select,"abc",11,22,33)', pcall(select,"abc",11,22,33) ) - - --- tonumber -print( 'pcall(tonumber)', pcall(tostring) ) -print( 'pcall(tonumber,nil)', pcall(tonumber,nil) ) -print( 'pcall(tonumber,"abc")', pcall(tonumber,"abc") ) -print( 'pcall(tonumber,"123")', pcall(tonumber,"123") ) -print( 'pcall(tonumber,"123",10)', pcall(tonumber,"123", 10) ) -print( 'pcall(tonumber,"123",8)', pcall(tonumber,"123", 8) ) -print( 'pcall(tonumber,"123",6)', pcall(tonumber,"123", 6) ) -print( 'pcall(tonumber,"10101",4)', pcall(tonumber,"10101", 4) ) -print( 'pcall(tonumber,"10101",3)', pcall(tonumber,"10101", 3) ) -print( 'pcall(tonumber,"10101",2)', pcall(tonumber,"10101", 2) ) -print( 'pcall(tonumber,"1a1",16)', pcall(tonumber,"1a1", 16) ) -print( 'pcall(tonumber,"1a1",32)', pcall(tonumber,"1a1", 32) ) -print( 'pcall(tonumber,"1a1",54)', pcall(tonumber,"1a1", 54) ) -print( 'pcall(tonumber,"1a1",1)', pcall(tonumber,"1a1", 1) ) -print( 'pcall(tonumber,"1a1",0)', pcall(tonumber,"1a1", 0) ) -print( 'pcall(tonumber,"1a1",-1)', pcall(tonumber,"1a1", -1) ) -print( 'pcall(tonumber,"1a1","32")', pcall(tonumber,"1a1", "32") ) -print( 'pcall(tonumber,"123","456")', pcall(tonumber,"123","456") ) -print( 'pcall(tonumber,"1a1",10)', pcall(tonumber,"1a1", 10) ) -print( 'pcall(tonumber,"151",4)', pcall(tonumber,"151", 4) ) -print( 'pcall(tonumber,"151",3)', pcall(tonumber,"151", 3) ) -print( 'pcall(tonumber,"151",2)', pcall(tonumber,"151", 2) ) -print( 'pcall(tonumber,"123",8,8)', pcall(tonumber,"123", 8, 8) ) -print( 'pcall(tonumber,123)', pcall(tonumber,123) ) -print( 'pcall(tonumber,true)', pcall(tonumber,true) ) -print( 'pcall(tonumber,false)', pcall(tonumber,false) ) -print( 'pcall(tonumber,tonumber)', pcall(tonumber,tonumber) ) -print( 'pcall(tonumber,function() end)', pcall(tonumber,function() end) ) -print( 'pcall(tonumber,{"one","two",a="aa",b="bb"})', pcall(tonumber,{"one","two",a="aa",b="bb"}) ) -print( 'pcall(tonumber,"123.456")', pcall(tonumber,"123.456") ) -print( 'pcall(tonumber," 123.456")', pcall(tonumber," 123.456") ) -print( 'pcall(tonumber," 234qwer")', pcall(tonumber," 234qwer") ) -print( 'pcall(tonumber,"0x20")', pcall(tonumber,"0x20") ) -print( 'pcall(tonumber," 0x20")', pcall(tonumber," 0x20") ) -print( 'pcall(tonumber,"0x20 ")', pcall(tonumber,"0x20 ") ) -print( 'pcall(tonumber," 0x20 ")', pcall(tonumber," 0x20 ") ) -print( 'pcall(tonumber,"0X20")', pcall(tonumber,"0X20") ) -print( 'pcall(tonumber," 0X20")', pcall(tonumber," 0X20") ) -print( 'pcall(tonumber,"0X20 ")', pcall(tonumber,"0X20 ") ) -print( 'pcall(tonumber," 0X20 ")', pcall(tonumber," 0X20 ") ) -print( 'pcall(tonumber,"0x20",10)', pcall(tonumber,"0x20",10) ) -print( 'pcall(tonumber,"0x20",16)', pcall(tonumber,"0x20",16) ) -print( 'pcall(tonumber,"0x20",8)', pcall(tonumber,"0x20",8) ) - --- tostring -print( 'pcall(tostring)', pcall(tostring) ) -print( 'pcall(tostring,nil)', pcall(tostring,nil) ) -print( 'pcall(tostring,"abc")', pcall(tostring,"abc") ) -print( 'pcall(tostring,"abc","def")', pcall(tostring,"abc","def") ) -print( 'pcall(tostring,123)', pcall(tostring,123) ) -print( 'pcall(tostring,true)', pcall(tostring,true) ) -print( 'pcall(tostring,false)', pcall(tostring,false) ) -print( 'tostring(tostring)', type(tostring(tostring)) ) -print( 'tostring(function() end)', type(tostring(function() end)) ) -print( 'tostring({"one","two",a="aa",b="bb"})', type(tostring({"one","two",a="aa",b="bb"})) ) - --- unpack -print( 'pcall(unpack)', pcall(unpack) ); -print( 'pcall(unpack,nil)', pcall(unpack,nil) ); -print( 'pcall(unpack,"abc")', pcall(unpack,"abc") ); -print( 'pcall(unpack,1)', pcall(unpack,1) ); -print( 'unpack({"aa"})', unpack({"aa"}) ); -print( 'unpack({"aa","bb"})', unpack({"aa","bb"}) ); -print( 'unpack({"aa","bb","cc"})', unpack({"aa","bb","cc"}) ); -local t = {"aa","bb","cc","dd","ee","ff"} -print( 'pcall(unpack,t)', pcall(unpack,t) ); -print( 'pcall(unpack,t,2)', pcall(unpack,t,2) ); -print( 'pcall(unpack,t,2,5)', pcall(unpack,t,2,5) ); -print( 'pcall(unpack,t,2,6)', pcall(unpack,t,2,6) ); -print( 'pcall(unpack,t,2,7)', pcall(unpack,t,2,7) ); -print( 'pcall(unpack,t,1)', pcall(unpack,t,1) ); -print( 'pcall(unpack,t,1,5)', pcall(unpack,t,1,5) ); -print( 'pcall(unpack,t,1,6)', pcall(unpack,t,1,6) ); -print( 'pcall(unpack,t,1,7)', pcall(unpack,t,1,7) ); -print( 'pcall(unpack,t,0)', pcall(unpack,t,0) ); -print( 'pcall(unpack,t,0,5)', pcall(unpack,t,0,5) ); -print( 'pcall(unpack,t,0,6)', pcall(unpack,t,0,6) ); -print( 'pcall(unpack,t,0,7)', pcall(unpack,t,0,7) ); -print( 'pcall(unpack,t,-1)', pcall(unpack,t,-1) ); -print( 'pcall(unpack,t,-1,5)', pcall(unpack,t,-1,5) ); -print( 'pcall(unpack,t,-1,6)', pcall(unpack,t,-1,6) ); -print( 'pcall(unpack,t,-1,7)', pcall(unpack,t,-1,7) ); -print( 'pcall(unpack,t,2,4)', pcall(unpack,t,2,4) ); -print( 'pcall(unpack,t,2,5)', pcall(unpack,t,2,5) ); -print( 'pcall(unpack,t,2,6)', pcall(unpack,t,2,6) ); -print( 'pcall(unpack,t,2,7)', pcall(unpack,t,2,7) ); -print( 'pcall(unpack,t,2,8)', pcall(unpack,t,2,8) ); -print( 'pcall(unpack,t,2,2)', pcall(unpack,t,2,0) ); -print( 'pcall(unpack,t,2,1)', pcall(unpack,t,2,0) ); -print( 'pcall(unpack,t,2,0)', pcall(unpack,t,2,0) ); -print( 'pcall(unpack,t,2,-1)', pcall(unpack,t,2,-1) ); -t[0] = 'zz' -t[-1] = 'yy' -t[-2] = 'xx' -print( 'pcall(unpack,t,0)', pcall(unpack,t,0) ); -print( 'pcall(unpack,t,2,0)', pcall(unpack,t,2,0) ); -print( 'pcall(unpack,t,2,-1)', pcall(unpack,t,2,-1) ); -print( 'pcall(unpack,t,"3")', pcall(unpack,t,"3") ); -print( 'pcall(unpack,t,"a")', pcall(unpack,t,"a") ); -print( 'pcall(unpack,t,function() end)', pcall(unpack,t,function() end) ); - --- _VERSION -print( '_VERSION', type(_VERSION) ) diff --git a/src/test/res/boolean.lua b/src/test/res/boolean.lua deleted file mode 100644 index 5209a69d..00000000 --- a/src/test/res/boolean.lua +++ /dev/null @@ -1,31 +0,0 @@ -t = true -f = false -n = nil -s = "Hello" -z = 0 -one = 1 - -print(t) -print(f) - -print(not t) -print(not f) -print(not n) -print(not z) -print(not s) -print(not(not(t))) -print(not(not(z))) -print(not(not(n))) - -print(t and f) -print(t or f) -print(f and t) -print(f or t) - -print(f or one) -print(f or z) -print(f or n) - -print(t and one) -print(t and z) -print(t and n) diff --git a/src/test/res/calls.lua b/src/test/res/calls.lua deleted file mode 100644 index a7a988de..00000000 --- a/src/test/res/calls.lua +++ /dev/null @@ -1,28 +0,0 @@ -local function f(x) - -- tailcall to a builtin - return math.sin(x) -end - -local function factorial(i) - local function helper(product, n) - if n <= 0 then - return product - else - -- tail call to a nested Lua function - return helper(n * product, n - 1) - end - end - return helper(1, i) -end - -local result1 = factorial(5) -print(result1) -print(factorial(5)) - -local function truncate(x) - local s = tostring(x) - return (#s<6 and s) or string.sub(s,1,6)..'...' -end -local result2 = f(math.pi) -print(truncate(result2)) -print(truncate(f(math.pi))) diff --git a/src/test/res/coercions.lua b/src/test/res/coercions.lua deleted file mode 100644 index 9db03f32..00000000 --- a/src/test/res/coercions.lua +++ /dev/null @@ -1,5 +0,0 @@ -print("5.0"+3.1) -print(4+"7.5") -print(3.14*" 2.75") -print("-33"/"11") -print(-"-5") diff --git a/src/test/res/compare.lua b/src/test/res/compare.lua deleted file mode 100644 index 6840009b..00000000 --- a/src/test/res/compare.lua +++ /dev/null @@ -1,12 +0,0 @@ -if 2 < 5 then - print("OK!") -else - print("Something is not right") -end - -print(2 < 5) -print(2 <= 5) -print(2 == 5) -print(2 ~= 5) -print(2 > 5) -print(2 >= 5) diff --git a/src/test/res/compile.sh b/src/test/res/compile.sh deleted file mode 100644 index eb930f15..00000000 --- a/src/test/res/compile.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -TESTS=`echo *.lua` -for x in $TESTS -do - echo compiling $x - luac -l -o ${x}c ${x} - lua ${x}c -done diff --git a/src/test/res/coroutines.lua b/src/test/res/coroutines.lua deleted file mode 100644 index 7b92dfca..00000000 --- a/src/test/res/coroutines.lua +++ /dev/null @@ -1,97 +0,0 @@ -function printrunning() - if coroutine.running() == nil then - print("running is nil"); - else - print("running is not nil") - end -end - -function foo (a) - print("foo", a) - return coroutine.yield(2*a) -end - -co = coroutine.create(function (a,b) - print("co-body", a, b) - local r = foo(a+1) - print("co-body", r) - local r, s = coroutine.yield(a+b, a-b) - print("co-body", r, s) - - printrunning() - print("co.status.inside",coroutine.status(co)); - local co2 = coroutine.create(function() - print("co.status.inside2",coroutine.status(co)); - end) - print("co.status.inside",coroutine.status(co)); - coroutine.resume(co2); - - return b, "end" -end) - -function exercise() - printrunning() - print("co.status",coroutine.status(co)); - print("main", coroutine.resume(co, 1, 10)) - print("co.status",coroutine.status(co)); - print("main", coroutine.resume(co, "r")) - print("co.status",coroutine.status(co)); - print("main", coroutine.resume(co, "x", "y")) - print("co.status",coroutine.status(co)); - print("main", coroutine.resume(co, "x", "y")) - print("co.status",coroutine.status(co)); -end - -exercise(); - -co = coroutine.create(function (a,b) - print("co-body", a, b) --- TODO: make java and C behave the same for yielding in pcalls --- local status,r = pcall( foo, a+1 ) -foo(a+1) - print("co-body", status,r) - local r, s = coroutine.yield(a+b, a-b) - print("co-body", r, s) - return b, "end" -end) - -exercise(); - - --- wrap test -local g = coroutine.wrap(function (a,b) - print("co-body", a, b) - local r = foo(a+1) - print("co-body", r) - local r, s = coroutine.yield(a+b, a-b) - print("co-body", r, s) - return b, "end" -end ) - -print("g", g(1, 10)) -print("g", g("r")) -print("g", g("x", "y")) -local s,e = pcall( g, "x", "y" ) -print("g", string.match(e,'cannot resume dead coroutine') or 'badmessage: '..tostring(e)) - --- varargs passing -local echo = function(msg,...) - print( msg, ...) - return ... -end -local echocr = function(...) - echo('(echocr) first args', unpack(arg,1,arg.n)) - local a = arg - while true do - a = { echo( '(echoch) yield returns', coroutine.yield( unpack(a) ) ) } - end -end -local c = coroutine.create( echocr ) -local step = function(...) - echo( '(main) resume returns', - coroutine.resume(c, echo('(main) sending args', ...)) ) -end -step(111,222,333) -step() -step(111) -step(111,222,333) diff --git a/src/test/res/debuglib.lua b/src/test/res/debuglib.lua deleted file mode 100644 index a3e52a77..00000000 --- a/src/test/res/debuglib.lua +++ /dev/null @@ -1,227 +0,0 @@ - -local print,tostring,_G,pcall,ipairs,isnumber = print,tostring,_G,pcall,ipairs,isnumber -local e,f,g,h,s -print( 'has debug', debug~=nil ) -if not debug then error( 'no debug' ) end - -print( '----- debug.getfenv, debug.setfenv' ) -f = function(a) - return 'f:'..tostring(a)..'|'..tostring(b) -end -s,e,g = pcall( debug.getfenv, f ) -print( s, type(e), type(g), (e==G), pcall( f, 'abc' ) ) -s,e,g = pcall( debug.setfenv, f, {b='def'} ) -print( s, type(e), type(g), (e==G), pcall( f, 'abc' ) ) -s,e,g = pcall( debug.getfenv, f ) -print( s, type(e), type(g), (e==G), pcall( f, 'abc' ) ) - - -print( '----- debug.getlocal, debug.setlocal' ) -h = function(v,i,n) - s = 'h-'..v..'-'..i - local x1,y1 = debug.getlocal(v,i) - local x2,y2 = debug.setlocal(v,i,n) - local x3,y3 = debug.getlocal(v,i) - return s..' -> '..v..'-'..i..' '.. - 'get='..tostring(x1)..','..tostring(y1)..' '.. - 'set='..tostring(x2)..','..tostring(y2)..' '.. - 'get='..tostring(x3)..','..tostring(y3)..' ' -end -g = function(...) - local p,q,r=7,8,9 - local t = h(...) - local b = table.concat({...},',') - return t..'\tg locals='..p..','..q..','..r..' tbl={'..b..'}' -end -f = function(a,b,c) - local d,e,f = 4,5,6 - local t = g(a,b,c) - return t..'\tf locals='..','..a..','..b..','..c..','..d..','..e..','..f -end -do lvl=1,1 - for lcl=3,7 do - print( pcall( f, lvl, lcl, '#' ) ) - end -end -do lvl=2,3 - for lcl=0,7 do - print( pcall( f, lvl, lcl, '#' ) ) - end -end - - -print( '----- debug.getupvalue, debug.setupvalue' ) -local m,n,o = 101,102,103 -f = function(p,q,r) - local p,q,r = 104,105,106 - local g = function(s,t,u) - local v,w,x = 107,108,109 - return function() - return m,n,o,p,q,r,v,w,x - end - end - return g -end -g = f() -h = g() -local callh = function() - local t = {} - for i,v in ipairs( { pcall(h) } ) do - t[i] = tostring(v) - end - return table.concat(t,',') -end -print( 'h', h() ) -local funs = { f, g, h } -local names = { 'f', 'g', 'h' } -for i=1,3 do - local fun,name = funs[i],names[i] - for index=0,10 do - local s1,x1,y1 = pcall( debug.getupvalue, fun, index ) - local s2,x2,y2 = pcall( debug.setupvalue, fun, index, 666000+i*111000+index ) - local s3,x3,y3 = pcall( debug.getupvalue, fun, index ) - print( name..' -> '..i..'-'..index..' '.. - 'get='..tostring(s1)..','..tostring(x1)..','..tostring(y1)..' '.. - 'set='..tostring(s2)..','..tostring(x2)..','..tostring(y2)..' '.. - 'get='..tostring(s3)..','..tostring(x3)..','..tostring(y3)..' '.. - 'tbl='..callh() ) - end -end - -print( '----- debug.setmetatable, debug.getmetatable' ) -local a = {a='bbb'} -local b = {} -local mt = {__index={b='ccc'}} -print( 'a.a='..tostring(a.a)..' a.b='..tostring(a.b)..' b.a='..tostring(b.a)..' b.b='..tostring(b.b)) -local s1,x1,y1 = pcall( debug.getmetatable, a ) -local s2,x2,y2 = pcall( debug.setmetatable, a, mt ) -print( 'a.a='..tostring(a.a)..' a.b='..tostring(a.b)..' b.a='..tostring(b.a)..' b.b='..tostring(b.b)) -local s3,x3,y3 = pcall( debug.getmetatable, a ) -local s4,x4,y4 = pcall( debug.getmetatable, b ) -local s5,x5,y5 = pcall( debug.setmetatable, a, nil ) -print( 'a.a='..tostring(a.a)..' a.b='..tostring(a.b)..' b.a='..tostring(b.a)..' b.b='..tostring(b.b)) -local s6,x6,y6 = pcall( debug.getmetatable, a ) -if not s1 then print( 's1 error', x1 ) end -if not s2 then print( 's2 error', x2 ) end -if not s3 then print( 's3 error', x3 ) end -if not s4 then print( 's4 error', x4 ) end -if not s5 then print( 's5 error', x5 ) end -if not s6 then print( 's6 error', x6 ) end -print( 'get='..tostring(s1)..','..tostring(x1==nil)..','..tostring(y1) ) -print( 'set='..tostring(s2)..','..tostring(x2==a)..','..tostring(y2) ) -print( 'get='..tostring(s3)..','..tostring(x3==mt)..','..tostring(y3) ) -print( 'get='..tostring(s4)..','..tostring(x4==nil)..','..tostring(y4) ) -print( 'set='..tostring(s5)..','..tostring(x5==a)..','..tostring(y5) ) -print( 'get='..tostring(s6)..','..tostring(x6==nil)..','..tostring(y6) ) -print( pcall( debug.getmetatable, 1 ) ) --- print( pcall( debug.setmetatable, 1, {} ) ) --- print( pcall( debug.setmetatable, 1, nil ) ) - -print( '----- debug.getinfo' ) -local printfield = function(tbl, field) - local x = tbl[field] - if x == nil then return end - local typ = type(x) - if typ=='table' then - x = '{'..table.concat(x,',')..'}' - elseif typ=='function' then - x = typ - end - print( ' '..field..': '..tostring(x) ) -end -local fields = { 'source', 'short_src', 'what', - 'currentline', 'linedefined', 'lastlinedefined', - 'nups', 'func', 'activelines' } -local printinfo = function(...) - for i,a in ipairs(arg) do - if type(a) == 'table' then - for j,field in ipairs(fields) do - printfield( a, field) - end - else - print( tostring(a) ) - end - end -end -function test() - local x = 5 - function f() - x = x + 1 - return x - end - function g() - x = x - 1 - print( '---' ) - printinfo( 'debug.getinfo(1)', debug.getinfo(1) ) - printinfo( 'debug.getinfo(1,"")', debug.getinfo(1, "") ) - printinfo( 'debug.getinfo(1,"l")', debug.getinfo(1, "l") ) - printinfo( 'debug.getinfo(1,"fL")', debug.getinfo(1, "fL") ) - printinfo( 'debug.getinfo(2)', debug.getinfo(2) ) - printinfo( 'debug.getinfo(2,"l")', debug.getinfo(2, "l") ) - printinfo( 'debug.getinfo(2,"fL")', debug.getinfo(2, "fL") ) - printinfo( 'debug.getinfo(10,"")', pcall( debug.getinfo, 10, "" ) ) - printinfo( 'debug.getinfo(-10,"")', pcall( debug.getinfo, -10, "" ) ) - --[[ - for i=1,3 do - printinfo( 'debug.traceback("msg")', debug.traceback('msg') ) - printinfo( 'debug.traceback("another",'..i..')', debug.traceback('another',i) ) - end - --]] - print( '---' ) - return x - end - print(f()) - print(g()) - return f, g -end - -local options = "nSlufL" -local e,f,g = pcall( test ) -print( 'e,f,g', e, type(f), type(g) ) -printinfo( 'debug.getinfo(f)', pcall(debug.getinfo, f) ) -printinfo( 'debug.getinfo(f,"'..options..'")', pcall(debug.getinfo, f, options) ) -for j=1,6 do - local opts = options:sub(j,j) - printinfo( 'debug.getinfo(f,"'..opts..'")', pcall(debug.getinfo, f, opts) ) -end -printinfo( 'debug.getinfo(g)', pcall(debug.getinfo, g) ) -printinfo( 'debug.getinfo(test)', pcall(debug.getinfo, test) ) - -print( '----- debug.sethook, debug.gethook' ) -f = function(x) - g = function(y) - return math.min(x,h) - end - local a = g(x) - return a + a -end -local hook = function(...) - print( ' ... in hook', ... ) -end -local tryfunc = function(hook,mask,func,arg) - local x,f,h,m - pcall( function() - debug.sethook(hook,mask) - x = func(arg) - f,h,m = debug.gethook() - end ) - debug.sethook() - return x,f,h,m -end - -local tryhooks = function(mask) - local s1,a1,b1,c1,d1 = pcall( tryfunc, hook, mask, f, 333 ) - print( 'hook = '..mask..' -> '.. - 'result='..tostring(s1)..','..tostring(a1)..','.. - type(b1)..','..type(c1)..','.. - tostring(b1==f)..','..tostring(c1==hook)..','.. - tostring(d1)..' ' ) -end ---[[ -tryhooks("c") -tryhooks("r") -tryhooks("l") -tryhooks("crl") ---]] - - \ No newline at end of file diff --git a/src/test/res/errors.lua b/src/test/res/errors.lua deleted file mode 100644 index 05092851..00000000 --- a/src/test/res/errors.lua +++ /dev/null @@ -1,121 +0,0 @@ --- object ids -package.path = "?.lua;src/test/res/?.lua" -require 'ids' - --- test of common types of errors -local function c(f,...) return f(...) end -local function b(...) return c(...) end -local function a(...) return (pcall(b,...)) end -s = 'some string' -local t = {} --- error message tests -print( 'a(error)', a(error) ) -print( 'a(error,"msg")', a(error,"msg") ) -print( 'a(error,"msg",0)', a(error,"msg",0) ) -print( 'a(error,"msg",1)', a(error,"msg",1) ) -print( 'a(error,"msg",2)', a(error,"msg",2) ) -print( 'a(error,"msg",3)', a(error,"msg",3) ) -print( 'a(error,"msg",4)', a(error,"msg",4) ) -print( 'a(error,"msg",5)', a(error,"msg",5) ) -print( 'a(error,"msg",6)', a(error,"msg",6) ) - --- call errors -print( 'a(nil())', a(function() return n() end) ) -print( 'a(t()) ', a(function() return t() end) ) -print( 'a(s()) ', a(function() return s() end) ) -print( 'a(true())', a(function() local b = true; return b() end) ) - --- arithmetic errors -print( 'a(nil+1)', a(function() return nil+1 end) ) -print( 'a(a+1) ', a(function() return a+1 end) ) -print( 'a(s+1) ', a(function() return s+1 end) ) -print( 'a(true+1)', a(function() local b = true; return b+1 end) ) - --- table errors -print( 'a(nil.x)', a(function() return n.x end) ) -print( 'a(a.x) ', a(function() return a.x end) ) -print( 'a(s.x) ', a(function() return s.x end) ) -print( 'a(true.x)', a(function() local b = true; return b.x end) ) -print( 'a(nil.x=5)', a(function() n.x=5 end) ) -print( 'a(a.x=5) ', a(function() a.x=5 end) ) -print( 'a(s.x=5) ', a(function() s.x=5 end) ) -print( 'a(true.x=5)', a(function() local b = true; b.x=5 end) ) - --- len operator -print( 'a(#nil) ', a(function() return #n end) ) -print( 'a(#t) ', a(function() return #t end) ) -print( 'a(#s) ', a(function() return #s end) ) -print( 'a(#a) ', a(function() return #a end) ) -print( 'a(#true)', a(function() local b = true; return #b end) ) - --- comparison errors -print( 'a(nil>1)', a(function() return nil>1 end) ) -print( 'a(a>1) ', a(function() return a>1 end) ) -print( 'a(s>1) ', a(function() return s>1 end) ) -print( 'a(true>1)', a(function() local b = true; return b>1 end) ) - --- unary minus errors -print( 'a(-nil)', a(function() return -n end) ) -print( 'a(-a) ', a(function() return -a end) ) -print( 'a(-s) ', a(function() return -s end) ) -print( 'a(-true)', a(function() local b = true; return -b end) ) - --- string concatenation -local function concatsuite(comparefunc) - print( '"a".."b"', comparefunc("a","b") ) - print( '"a"..nil', comparefunc("a",nil) ) - print( 'nil.."b"', comparefunc(nil,"b") ) - print( '"a"..{}', comparefunc("a",{}) ) - print( '{}.."b"', comparefunc({},"b") ) - print( '"a"..2', comparefunc("a",2) ) - print( '2.."b"', comparefunc(2,"b") ) - print( '"a"..print', comparefunc("a",print) ) - print( 'print.."b"', comparefunc(print,"b") ) - print( '"a"..true', comparefunc("a",true) ) - print( 'true.."b"', comparefunc(true,"b") ) - print( 'nil..true', comparefunc(nil,true) ) - print( '"a"..3.5', comparefunc("a",3.5) ) - print( '3.5.."b"', comparefunc(3.5,"b") ) -end -local function strconcat(a,b) - return (pcall( function() return a..b end) ) -end -local function tblconcat(a,b) - local t={a,b} - return (pcall( function() return table.concat(t,'-') end )) -end --- concatsuite(strconcat) -concatsuite(tblconcat) - --- pairs -print( 'a(pairs(nil))', a(function() return id(pairs(nil,{})) end) ) -print( 'a(pairs(a)) ', a(function() return id(pairs(a,{})) end) ) -print( 'a(pairs(s)) ', a(function() return id(pairs(s,{})) end) ) -print( 'a(pairs(t)) ', a(function() return id(pairs(t,{})) end) ) -print( 'a(pairs(true))', a(function() local b = true; return id(pairs(b,{})) end) ) - --- setmetatable -function sm(...) - return id(setmetatable(...)) -end -print( 'a(setmetatable(nil))', a(function() return sm(nil,{}) end) ) -print( 'a(setmetatable(a)) ', a(function() return sm(a,{}) end) ) -print( 'a(setmetatable(s)) ', a(function() return sm(s,{}) end) ) -print( 'a(setmetatable(true))', a(function() local b = true; return sm(b,{}) end) ) -print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) ) -print( 'a(setmetatable(t*)) ', a(function() return sm(t,{__metatable={}}) end) ) -print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) ) -t = {} -print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) ) -print( 'a(setmetatable(t*)) ', a(function() return sm(t,{__metatable='some string'}) end) ) -print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) ) -print( 'a(setmetatable(t,nil)) ', a(function() return sm(t,nil) end) ) -print( 'a(setmetatable(t)) ', a(function() return sm(t) end) ) -print( 'a(setmetatable({},"abc")) ', a(function() return sm({},'abc') end) ) - --- bad args to error! -print( 'error("msg","arg")', a(function() error('some message', 'some bad arg') end) ) - --- loadfile, dofile on missing files -print( 'loadfile("bogus.txt")', a(function() return loadfile("bogus.txt") end) ) -print( 'dofile("bogus.txt")', a(function() return dofile("bogus.txt") end) ) diff --git a/src/test/res/hugetable.lua b/src/test/res/hugetable.lua deleted file mode 100644 index 566e03cb..00000000 --- a/src/test/res/hugetable.lua +++ /dev/null @@ -1,43 +0,0 @@ --- test tables with more than 50 elements - -local t = { 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1, - } -print ("#t=",#t,'t[1,50,51,59]', t[1], t[50], t[51], t[59]) -print (table.concat(t,',')) - -local t2= { 0,3,4,7,9,8,12,15,23,5, - 10,13,14,17,19,18,112,115,123,15, - 20,33,24,27,29,28,212,215,223,25, - 40,43,44,47,49,48,412,415,423,45, - 50,53,54,57,59,58,512,515,523,55, - 60,63,64,67,69,68,612,615,623,65, - 70,73,74,77,79,78,72,715,723,75, - } - -print ("#t2=",#t2,'t[1,50,51,59]', t[1], t[50], t[51], t[59]) -print (table.concat(t2,',')) - -local t = { - [2000]='a', [2001]='b', [2002]='c', [2003]='d', [2004]='e', [2005]='f', [2006]='g', [2007]='h', [2008]='i', [2009]='j', - [3000]='a', [3001]='b', [3002]='c', [3003]='d', [3004]='e', [3005]='f', [3006]='g', [3007]='h', [3008]='i', [3009]='j', - [4000]='a', [4001]='b', [4002]='c', [4003]='d', [4004]='e', [4005]='f', [4006]='g', [4007]='h', [4008]='i', [4009]='j', - [5000]='a', [5001]='b', [5002]='c', [5003]='d', [5004]='e', [5005]='f', [5006]='g', [5007]='h', [5008]='i', [5009]='j', - [6000]='a', [6001]='b', [6002]='c', [6003]='d', [6004]='e', [6005]='f', [6006]='g', [6007]='h', [6008]='i', [6009]='j', - [7000]='a', [7001]='b', [7002]='c', [7003]='d', [7004]='e', [7005]='f', [7006]='g', [7007]='h', [7008]='i', [7009]='j', - [8000]='a', [8001]='b', [8002]='c', [8003]='d', [8004]='e', [8005]='f', [8006]='g', [8007]='h', [8008]='i', [8009]='j', -} - -for i=2000,8000,1000 do - for j=0,9,1 do - print( 't['..tostring(i+j)..']', t[i+j] ) - end -end diff --git a/src/test/res/ids.lua b/src/test/res/ids.lua deleted file mode 100644 index a1ca7283..00000000 --- a/src/test/res/ids.lua +++ /dev/null @@ -1,36 +0,0 @@ --- utility to give tables and functions uniform ids for testing -ids = {} - --- return unique id for the value, independent of object id -function id(obj) - if not obj or type(obj) == 'number' or type(obj) == 'string' or type(obj) == 'boolean' then - return obj - end - local v = ids[obj] - if v then - return v - end - table.insert(ids,obj) - ids[obj] = type(obj)..'.'..tostring(#ids) - return ids[obj] -end - --- return key-value pairs sorted by keys -function spairs(unsorted) - local keys = {} - for k,v in pairs(unsorted) do - table.insert(keys,k) - end - table.sort(keys) - local lookup = {} - for i,k in ipairs(keys) do - lookup[k] = i; - end - local iterator = function(tbl,key) - local i = lookup[key] - local j,k = next(keys,i) - if not j then return nil end - return k,unsorted[k] - end - return iterator, table, nil -end \ No newline at end of file diff --git a/src/test/res/iolib.lua b/src/test/res/iolib.lua deleted file mode 100644 index 5a309beb..00000000 --- a/src/test/res/iolib.lua +++ /dev/null @@ -1,115 +0,0 @@ --- simple io-library tests -print( io ~= nil ) -print( io.open ~= nil ) -print( io.stdin ~= nil ) -print( io.stdout ~= nil ) -print( io.stderr ~= nil ) -print( 'write', io.write() ) -print( 'write', io.write("This") ) -print( 'write', io.write(" is a pen.\n") ) -print( 'flush', io.flush() ) - -local f = io.open("abc.txt","w") -print( 'f', type(f) ) -print( io.type(f) ) -print( 'write', f:write("abcdef 12345 \t\r\n\t 678910 more\naaaaaa\rbbb\nthe rest") ) -print( 'type(f)', io.type(f) ) -print( 'close', f:close() ) -print( 'type(f)', io.type(f) ) -print( 'type("f")', io.type("f") ) - -local g = io.open("abc.txt","r") -local t = { g:read(3, 3, "*n", "*n", "*l", "*l", "*a") } -for i,v in ipairs(t) do - print( string.format("%q",tostring(v)), type(v)) -end - -local h,s = io.open("abc.txt", "a") -print( 'h', io.type(h), s ) -print( 'write', h:write('\nmore text\neven more text\n') ) -print( 'close', h:close() ) - -local j = io.open( "abc.txt", "r" ) -print( 'j', io.type(j) ) -print( 'seek', j:seek("set", 3) ) -print( 'read', j:read(4), j:read(3) ) -print( 'seek', j:seek("set", 2) ) -print( 'read', j:read(4), j:read(3) ) -print( 'seek', j:seek("cur", -8 ) ) -print( 'read', j:read(4), j:read(3) ) -print( 'seek(cur,0)', j:seek("cur",0) ) -print( 'seek(cur,20)', j:seek("cur",20) ) -print( 'seek(end,-5)', j:seek("end", -5) ) -print( 'read(4)', string.format("%q", tostring(j:read(4))) ) -print( 'read(4)', string.format("%q", tostring(j:read(4))) ) -print( 'read(4)', string.format("%q", tostring(j:read(4))) ) - -for l in io.lines("abc.txt") do - print( string.format('%q',l) ) -end -io.input("abc.txt") -for l in io.lines() do - print( string.format('%q',l) ) -end -io.input(io.open("abc.txt","r")) -for l in io.lines() do - print( string.format('%q',l) ) -end -io.input("abc.txt") -io.input(io.input()) -for l in io.lines() do - print( string.format('%q',l) ) -end - -local count = 0 -io.tmpfile = function() - count = count + 1 - return io.open("tmp"..count..".out","w") -end - -local a = io.tmpfile() -local b = io.tmpfile() -print( io.type(a) ) -print( io.type(b) ) -print( "a:write", a:write('aaaaaaa') ) -print( "b:write", b:write('bbbbbbb') ) -print( "a:setvbuf", a:setvbuf("no") ) -print( "a:setvbuf", a:setvbuf("full",1024) ) -print( "a:setvbuf", a:setvbuf("line") ) -print( "a:write", a:write('ccccc') ) -print( "b:write", b:write('ddddd') ) -print( "a:flush", a:flush() ) -print( "b:flush", b:flush() ) ---[[ -print( "a:read", a:read(7) ) -print( "b:read", b:read(7) ) -print( "a:seek", a:seek("cur",-4) ) -print( "b:seek", b:seek("cur",-4) ) -print( "a:write", a:read(7) ) -print( "b:write", b:read(7) ) ---]] - -local pcall = function(...) return ( pcall(...) )end - -print( 'a:close', pcall( a.close, a ) ) -print( 'a:write', pcall( a.write, a, 'eee') ) -print( 'a:flush', pcall( a.flush, a) ) -print( 'a:read', pcall( a.read, a, 5) ) -print( 'a:lines', pcall( a.lines, a) ) -print( 'a:seek', pcall( a.seek, a, "cur", -2) ) -print( 'a:setvbuf', pcall( a.setvbuf, a, "no") ) -print( 'a:close', pcall( a.close, a ) ) -print( 'io.type(a)', pcall( io.type, a ) ) - -print( 'io.close()', pcall( io.close ) ) -print( 'io.close(io.output())', pcall( io.close, io.output() ) ) - -io.output('abc.txt') -print( 'io.close()', pcall( io.close ) ) -print( 'io.write', pcall( io.write, 'eee') ) -print( 'io.flush', pcall( io.flush) ) -print( 'io.close', pcall( io.close ) ) -io.input('abc.txt'):close() -print( 'io.read', pcall( io.read, 5) ) -print( 'io.lines', pcall( io.lines) ) - diff --git a/src/test/res/loops.lua b/src/test/res/loops.lua deleted file mode 100644 index 431374c8..00000000 --- a/src/test/res/loops.lua +++ /dev/null @@ -1,22 +0,0 @@ --- This script tests the "generic" for loop with a script iterator. - -local function stuff() - local function i(o) - if o.counter > 3 then - return nil - else - local v = o.counter - o.counter = v + 1 - return v - end - end - return i, { counter=1 } -end - -local function testfor() - for x in stuff() do - print(x) - end -end - -testfor() diff --git a/src/test/res/manylocals.lua b/src/test/res/manylocals.lua deleted file mode 100644 index c45179c5..00000000 --- a/src/test/res/manylocals.lua +++ /dev/null @@ -1,31 +0,0 @@ --- test program with more than 50 non-sequential integer elements -local t0000='a'; local t0001='b'; local t0002='c'; local t0003='d'; local t0004='e'; local t0005='f'; local t0006='g'; local t0007='h'; local t0008='i'; local t0009='j'; -local t1000='a'; local t1001='b'; local t1002='c'; local t1003='d'; local t1004='e'; local t1005='f'; local t1006='g'; local t1007='h'; local t1008='i'; local t1009='j'; -local t2000='a'; local t2001='b'; local t2002='c'; local t2003='d'; local t2004='e'; local t2005='f'; local t2006='g'; local t2007='h'; local t2008='i'; local t2009='j'; -local t3000='a'; local t3001='b'; local t3002='c'; local t3003='d'; local t3004='e'; local t3005='f'; local t3006='g'; local t3007='h'; local t3008='i'; local t3009='j'; -local t4000='a'; local t4001='b'; local t4002='c'; local t4003='d'; local t4004='e'; local t4005='f'; local t4006='g'; local t4007='h'; local t4008='i'; local t4009='j'; -local t5000='a'; local t5001='b'; local t5002='c'; local t5003='d'; local t5004='e'; local t5005='f'; local t5006='g'; local t5007='h'; local t5008='i'; local t5009='j'; -local t6000='a'; local t6001='b'; local t6002='c'; local t6003='d'; local t6004='e'; local t6005='f'; local t6006='g'; local t6007='h'; local t6008='i'; local t6009='j'; -local t7000='a'; local t7001='b'; local t7002='c'; local t7003='d'; local t7004='e'; local t7005='f'; local t7006='g'; local t7007='h'; local t7008='i'; local t7009='j'; -local t8000='a'; local t8001='b'; local t8002='c'; local t8003='d'; local t8004='e'; local t8005='f'; local t8006='g'; local t8007='h'; local t8008='i'; local t8009='j'; -local t9000='a'; local t9001='b'; local t9002='c'; local t9003='d'; local t9004='e'; local t9005='f'; local t9006='g'; local t9007='h'; local t9008='i'; local t9009='j'; -local t10000='a'; local t10001='b'; local t10002='c'; local t10003='d'; local t10004='e'; local t10005='f'; local t10006='g'; local t10007='h'; local t10008='i'; local t10009='j'; -local t11000='a'; local t11001='b'; local t11002='c'; local t11003='d'; local t11004='e'; local t11005='f'; local t11006='g'; local t11007='h'; local t11008='i'; local t11009='j'; -local t12000='a'; local t12001='b'; local t12002='c'; local t12003='d'; local t12004='e'; local t12005='f'; local t12006='g'; local t12007='h'; local t12008='i'; local t12009='j'; -local t13000='a'; local t13001='b'; local t13002='c'; local t13003='d'; local t13004='e'; local t13005='f'; local t13006='g'; local t13007='h'; local t13008='i'; local t13009='j'; - --- print the variables -print(t0000,'a'); print(t0001,'b'); print(t0002,'c'); print(t0003,'d'); print(t0004,'e'); print(t0005,'f'); print(t0006,'g'); print(t0007,'h'); print(t0008,'i'); print(t0009,'j'); -print(t1000,'a'); print(t1001,'b'); print(t1002,'c'); print(t1003,'d'); print(t1004,'e'); print(t1005,'f'); print(t1006,'g'); print(t1007,'h'); print(t1008,'i'); print(t1009,'j'); -print(t2000,'a'); print(t2001,'b'); print(t2002,'c'); print(t2003,'d'); print(t2004,'e'); print(t2005,'f'); print(t2006,'g'); print(t2007,'h'); print(t2008,'i'); print(t2009,'j'); -print(t3000,'a'); print(t3001,'b'); print(t3002,'c'); print(t3003,'d'); print(t3004,'e'); print(t3005,'f'); print(t3006,'g'); print(t3007,'h'); print(t3008,'i'); print(t3009,'j'); -print(t4000,'a'); print(t4001,'b'); print(t4002,'c'); print(t4003,'d'); print(t4004,'e'); print(t4005,'f'); print(t4006,'g'); print(t4007,'h'); print(t4008,'i'); print(t4009,'j'); -print(t5000,'a'); print(t5001,'b'); print(t5002,'c'); print(t5003,'d'); print(t5004,'e'); print(t5005,'f'); print(t5006,'g'); print(t5007,'h'); print(t5008,'i'); print(t5009,'j'); -print(t6000,'a'); print(t6001,'b'); print(t6002,'c'); print(t6003,'d'); print(t6004,'e'); print(t6005,'f'); print(t6006,'g'); print(t6007,'h'); print(t6008,'i'); print(t6009,'j'); -print(t7000,'a'); print(t7001,'b'); print(t7002,'c'); print(t7003,'d'); print(t7004,'e'); print(t7005,'f'); print(t7006,'g'); print(t7007,'h'); print(t7008,'i'); print(t7009,'j'); -print(t8000,'a'); print(t8001,'b'); print(t8002,'c'); print(t8003,'d'); print(t8004,'e'); print(t8005,'f'); print(t8006,'g'); print(t8007,'h'); print(t8008,'i'); print(t8009,'j'); -print(t9000,'a'); print(t9001,'b'); print(t9002,'c'); print(t9003,'d'); print(t9004,'e'); print(t9005,'f'); print(t9006,'g'); print(t9007,'h'); print(t9008,'i'); print(t9009,'j'); -print(t10000,'a'); print(t10001,'b'); print(t10002,'c'); print(t10003,'d'); print(t10004,'e'); print(t10005,'f'); print(t10006,'g'); print(t10007,'h'); print(t10008,'i'); print(t10009,'j'); -print(t11000,'a'); print(t11001,'b'); print(t11002,'c'); print(t11003,'d'); print(t11004,'e'); print(t11005,'f'); print(t11006,'g'); print(t11007,'h'); print(t11008,'i'); print(t11009,'j'); -print(t12000,'a'); print(t12001,'b'); print(t12002,'c'); print(t12003,'d'); print(t12004,'e'); print(t12005,'f'); print(t12006,'g'); print(t12007,'h'); print(t12008,'i'); print(t12009,'j'); -print(t13000,'a'); print(t13001,'b'); print(t13002,'c'); print(t13003,'d'); print(t13004,'e'); print(t13005,'f'); print(t13006,'g'); print(t13007,'h'); print(t13008,'i'); print(t13009,'j'); diff --git a/src/test/res/math.lua b/src/test/res/math.lua deleted file mode 100644 index 13dc6b8d..00000000 --- a/src/test/res/math.lua +++ /dev/null @@ -1,7 +0,0 @@ -local mathClass = luajava.bindClass("java.lang.Math") - -local function sqrt(x) - return mathClass:sqrt(x) -end - -return { sqrt = sqrt; pi = mathClass.PI } diff --git a/src/test/res/mathlib.lua b/src/test/res/mathlib.lua deleted file mode 100644 index 49d47be0..00000000 --- a/src/test/res/mathlib.lua +++ /dev/null @@ -1,87 +0,0 @@ -print( math.sin( 0.0 ) ) -print( math.cos( math.pi ) ) -print( math.sqrt( 9.0 ) ) -print( math.modf( 5.25 ) ) - -local aliases = { - ['0']='', - ['-0']='', - ['nan']='', - ['inf']='', - ['-inf']='', - ['1.#INF']='', - ['-1.#INF']='', - ['1.#IND']='', - ['-1.#IND']='', -} - -local function normalized(x) - local s = tostring(x) - return aliases[s] or s -end - --- binary ops -function binops( a, b ) - local sa = tostring(a) - local sb = tostring(b) - print( sa..'+'..sb..'='..normalized(a+b) ) - print( sa..'-'..sb..'='..normalized(a-b) ) - print( sa..'*'..sb..'='..normalized(a*b) ) - print( sa..'^'..sb..'='..normalized(a^b) ) - print( sa..'/'..sb..'='..normalized(a/b) ) - print( sa..'%'..sb..'='..normalized(a%b) ) - return '--' -end -print( pcall( binops, 2, 0 ) ) -print( pcall( binops, 2.5, 0 ) ) -print( pcall( binops, -2.5, 0 ) ) -print( pcall( binops, 2, 1 ) ) -print( pcall( binops, 5, 2 ) ) -print( pcall( binops, -5, 2 ) ) -print( pcall( binops, 16, -2 ) ) -print( pcall( binops, -16, -2 ) ) -print( pcall( binops, 256, 0.5 ) ) -print( pcall( binops, 256, 0.25 ) ) -print( pcall( binops, 256, 0.625 ) ) -print( pcall( binops, 256, -0.5 ) ) -print( pcall( binops, 256, -0.25 ) ) -print( pcall( binops, 256, -0.625 ) ) -print( pcall( binops, -256, 0.5 ) ) -print( pcall( binops, 0.5, 0 ) ) -print( pcall( binops, 0.5, 1 ) ) -print( pcall( binops, 0.5, 2 ) ) -print( pcall( binops, 0.5, -1 ) ) -print( pcall( binops, 0.5, -2 ) ) -print( pcall( binops, 2.25, 0 ) ) -print( pcall( binops, 2.25, 2 ) ) -print( pcall( binops, 2.25, 0.5 ) ) -print( pcall( binops, 2.25, 2.5 ) ) -print( pcall( binops, -2, 0 ) ) - --- random tests -print("Random tests") -local function testrandom(string,lo,hi) - local c,e = loadstring('return '..string) - for i=1,5 do - local s,e = pcall(c) - print( string, s and type(e) or e, (e>=lo) and (e<=hi) ) - end -end -testrandom('math.random()',0,1) -testrandom('math.random(5,10)',5,10) -testrandom('math.random(30)',0,30) -testrandom('math.random(-4,-2)',-4,-2) -local t = {} -print( math.randomseed(20) ) -for i=1,20 do - t[i] = math.random() -end -print( '-- comparing new numbers') -for i=1,20 do - print( t[i] == math.random(), t[i] == t[0] ) -end -print( '-- resetting seed') -print( math.randomseed(20) ) -for i=1,20 do - print( t[i] == math.random() ) -end diff --git a/src/test/res/metatables.lua b/src/test/res/metatables.lua deleted file mode 100644 index e18be17d..00000000 --- a/src/test/res/metatables.lua +++ /dev/null @@ -1,48 +0,0 @@ -package.path = "?.lua;src/test/res/?.lua" -require 'ids' - --- The purpose of this test case is to demonstrate that --- basic metatable operations on non-table types work. --- i.e. that s.sub(s,...) could be used in place of string.sub(s,...) -local s = "hello" -print(s:sub(2,4)) - -local t = {} -function op(name,...) - local a,b = pcall( setmetatable, t, ... ) - print( name, id(t), id(getmetatable(t)), id(a), a and id(b) or type(b) ) -end -op('set{} ',{}) -op('set-nil',nil) -op('set{} ',{}) -op('set') -op('set{} ',{}) -op('set{} ',{}) -op('set{}{}',{},{}) -op('set-nil',nil) -op('set{__}',{__metatable={}}) -op('set{} ',{}) -op('set-nil',nil) -t = {} -op('set{} ',{}) -op('set-nil',nil) -op('set{__}',{__metatable='abc'}) -op('set{} ',{}) -op('set-nil',nil) - - -local i = 1234 -local t = setmetatable( {}, { - __mode="v", - __index=function(t,k) - local v = i - i = i + 1 - rawset(t,k,v) - return v - end, -} ) - -local l = { 'a', 'b', 'a', 'b', 'c', 'a', 'b', 'c', 'd' } -for i,key in ipairs(l) do - print( 't.'..key, t[key] ) -end \ No newline at end of file diff --git a/src/test/res/module.lua b/src/test/res/module.lua deleted file mode 100644 index cce7ddfa..00000000 --- a/src/test/res/module.lua +++ /dev/null @@ -1,90 +0,0 @@ - - --- unit tests for module() function -local ids = {} -local function id(obj) - if not obj or type(obj) == 'number' or type(obj) == 'string' then - return obj - end - local v = ids[obj] - if v then - return v - end - table.insert(ids,obj) - ids[obj] = type(obj)..'.'..tostring(#ids) - return ids[obj] -end - --- module tests -local pr = print -local pkg = package -local g = _G -local md = module -local rq = require -local sa = package.seeall -local gfe = getfenv -local gmt = getmetatable -local function envs() - return id(gfe(0)), id(gfe(1)), id(gfe(2)), - id(gmt(gfe(0))), id(gmt(gfe(1))), id(gmt(gfe(2))) -end -local function trymodule(name) - pr( '_G['..name..']', id(g[name]) ) - pr( 'pkg.loaded['..name..']', id(pkg.loaded[name]) ) - pr( 'envs', envs() ) - md(name) - pr( 'envs', envs() ) - pr( 'status,result', status, result ) - pr( '_G['..name..']', id(g[name]) ) - local t = pkg.loaded[name] - pr( 't=pkg.loaded['..name..']', id(t) ) - pr( 't._M, t._NAME, t._PACKAGE', id(t._M), id(t._NAME), id(t._PACKAGE) ) - pr( 'rq('..name..')', id( rq(name) ) ) - pr( 'print', id(print) ) - pr( 'seeall(t)', sa(t) ) - pr( 'print, _G['..name..']', id(print), id(g[name]) ) -end -trymodule('abc.def.ghi') -trymodule('abc.def.ghi') -trymodule('abc.def') -trymodule('abc.def.lmn') -trymodule('abc.def') -trymodule('abc') -package.loaded['opq.rst'] = {} -trymodule('opq.rst') -trymodule('opq.rst') -uvw = { xyz="x1y1z1" } ---print( "uvw", id(uvw) ) ---print( "uvw.xyz", id(uvw.xyz) ) ---print( "uvw.abc", id(uvw.abc) ) -print( pcall( trymodule, 'uvw.xyz' ) ) -print( pcall( trymodule, 'uvw' ) ) -print( pcall( trymodule, 'uvw.abc' ) ) -print( "uvw", id(uvw) ) -print( "uvw.xyz", id(uvw.xyz) ) -print( "uvw.abc", id(uvw.abc) ) - -function f() - module( 'fff', package.seeall ) - a = 'aaa' - print( a ) - end -f() -f() -print( a ) -print( getfenv(f)['a'] ) -print( a ) - --- do metatables work with package.loaded and require? -print( 'setting metatable for package.loaded' ) -print( 'package.loaded.mypreload', package.loaded.mypreload ) -print( 'setmetatable') -pcall( setmetatable, package.loaded, { __index={mypreload=12345}}) -print( 'package.loaded.mypreload', package.loaded.mypreload ) -print( "require, 'mypreload'", pcall( require, 'mypreload' ) ) -print( 'package.loaded.mypreload', package.loaded.mypreload ) -print( 'resetting metatable for package.loaded' ) -print( 'setmetatable') -pcall( setmetatable, package.loaded, nil ) -print( "require, 'mypreload'", (pcall( require, 'mypreload' )) ) -print( 'package.loaded.mypreload', package.loaded.mypreload ) diff --git a/src/test/res/next.lua b/src/test/res/next.lua deleted file mode 100644 index 36465713..00000000 --- a/src/test/res/next.lua +++ /dev/null @@ -1,37 +0,0 @@ - --- call with arg 'true' to turn on error messages -local messages = select(1,...) -function mpcall(...) - if messages then return pcall(...) - else return (pcall(...)) end -end - --- unit tests for the next() function -function checkvalues(tag, tbl) - local values = {} - local index,value = next(tbl,nil) - while index do - table.insert( values, tostring(index).."="..tostring(value) ) - index,value = next(tbl,index) - end - table.sort( values ) - print( tag, "values: {"..table.concat(values,",").."}" ) -end -function donexts(tag,tbl,count) - checkvalues(tag,tbl) - print( tag, '--- -1', 'pcall( next, tbl,-1 )', mpcall( next, tbl,-1 ) ) - print( tag, '--- 0', 'pcall( next, tbl,0 )', mpcall( next, tbl,0 ) ) - print( tag, '---"a"', 'pcall( next, tbl,"a" )', mpcall( next, tbl,"a" ) ) - print( tag, '--- 10', 'pcall( next, tbl, 10 )', mpcall( next, tbl, 10 ) ) -end -donexts( 'next1', {}, 2 ) -donexts( 'next2', {'one', 'two', 'three' }, 5 ) -donexts( 'next3', { aa='aaa', bb='bbb', cc='ccc', [20]='20', [30]='30'}, 7 ) -donexts( 'next4', {'one', 'two', 'three', aa='aaa', bb='bbb', cc='ccc', [20]='20', [30]='30'}, 9 ) -donexts( 'next5', {'one', 'two', 'three', [-1]='minus-one', [0]='zero' }, 7 ) - -print( 'pcall(next)', mpcall(next) ) -print( 'pcall(next,nil)', mpcall(next,nil) ) -print( 'pcall(next,"a")', mpcall(next,"a") ) -print( 'pcall(next,1)', mpcall(next,1) ) - diff --git a/src/test/res/oslib.lua b/src/test/res/oslib.lua deleted file mode 100644 index a728c17c..00000000 --- a/src/test/res/oslib.lua +++ /dev/null @@ -1,36 +0,0 @@ --- simple os-library tests --- these can't really be compared to C meaningfully, --- because they are so highly os-dependent. -local lib = "org.luaj.lib.j2se.J2seOsLib" --- local lib = "org.luaj.lib.OsLib" -print( 'require "'..lib..'"', pcall( require, lib ) ) -print( 'os', os ~= nil ) -print( 'os.clock()', pcall( os.clock ) ) -print( 'os.date()', pcall( os.date ) ) -print( 'os.difftime(123000, 21250)', pcall( os.difftime, 123000, 21250 ) ) -print( 'os.execute("hostname")', pcall( os.execute, 'hostname' ) ) -print( 'os.execute("")', pcall( os.execute, '' ) ) -print( 'os.getenv()', pcall( os.getenv ) ) -print( 'os.getenv("bogus.key")', pcall( os.getenv, 'bogus.key' ) ) -print( 'os.getenv("java.runtime.version")', pcall( os.getenv, 'java.runtime.version' ) ) -local s,p = pcall( os.tmpname ) -local s,q = pcall( os.tmpname ) -print( 'os.tmpname()', s, p ) -print( 'os.tmpname()', s, q ) -print( 'os.remove(p)', pcall( os.remove, p ) ) -print( 'os.rename(p,q)', pcall( os.rename, p, q ) ) -local s,f = pcall( io.open, p,"w" ) -print( 'io.open', s, f ) -print( 'write', pcall( f.write, f, "abcdef 12345" ) ) -print( 'close', pcall( f.close, f ) ) -print( 'os.rename(p,q)', pcall( os.rename, p, q ) ) -print( 'os.remove(q)', pcall( os.remove, q ) ) -print( 'os.remove(q)', pcall( os.remove, q ) ) -print( 'os.setlocale()', pcall( os.setlocale ) ) -print( 'os.setlocale("jp")', pcall( os.setlocale, "jp" ) ) -print( 'os.setlocale("us","monetary")', pcall( os.setlocale, "us", "monetary" ) ) -print( 'os.setlocale(nil,"all")', pcall( os.setlocale, nil, "all" ) ) -print( 'os.setlocale("c")', pcall( os.setlocale, "c" ) ) -print( 'os.exit(123)' ) --- print( pcall( os.exit, -123 ) ) -print( 'failed to exit' ) diff --git a/src/test/res/pcalls.lua b/src/test/res/pcalls.lua deleted file mode 100644 index 689b0e64..00000000 --- a/src/test/res/pcalls.lua +++ /dev/null @@ -1,75 +0,0 @@ - --- sample lua function that returns values in reverse order -local function lc(a,b,c) - return c,b,a -end - --- sample lua function that throws a lua error -local function le(a,b,c) - error( 'sample error', 0 ) -end - --- function that does a plain call to the underlying function -local function cp(f,a,b,c) - global = f(a,b,c) - return global -end - --- function that does a tail call to the underlying function -local function ct(f,a,b,c) - return f(a,b,c) -end - --- wrap pcall to be more useful in testing -local pc = pcall -local pcall = function(...) - local s,c = pc(...) - return s, type(c) -end - --- lua calls -print( 'lc(22,33,44)', lc(22,33,44) ) -print( 'pcall(lc,22,33,44)', pcall(lc,22,33,44) ) -print( 'pcall(le,22,33,44)', pcall(le,22,33,44) ) -print( 'cp(lc,22,33,44)', cp(lc,22,33,44) ) -print( 'pcall(cp,lc,22,33,44)', pcall(cp,lc,22,33,44) ) -print( 'pcall(cp,le,22,33,44)', pcall(cp,le,22,33,44) ) -print( 'ct(lc,22,33,44)', ct(lc,22,33,44) ) -print( 'pcall(ct,lc,22,33,44)', pcall(ct,lc,22,33,44) ) -print( 'pcall(ct,le,22,33,44)', pcall(ct,le,22,33,44) ) - -print( "assert(true,'a','b','c')", assert( true, 'a', 'b', 'c' ) ) -print( "pcall(assert,true,'a','b','c')", pcall(assert, true, 'a', 'b', 'c' ) ) -print( "pcall(assert,false,'a','b','c')", pcall(assert, false, 'a', 'b', 'c' ) ) - --- more error, pcall tests -print( 'pcall(error)', pcall(error) ) -print( 'pcall(error,"msg")', pcall(error,"msg") ) -print( 'pcall(error,"msg",1)', pcall(error,"msg",1) ) -print( 'pcall(error,"msg",2)', pcall(error,"msg",2) ) -local function le(level) - error("msg",level) -end -function ge(level) - error("msg",level) -end -for i = 0,4 do - print( 'pcall(le,i)', i, pcall(le,i) ) - print( 'pcall(ge,i)', i, pcall(ge,i) ) -end - --- xpcall tests -local function goodfunction() return 'from good function' end -local function badfunction() error( 'from bad function') end -local function goodhandler(msg) return '-->'..msg..'<--' end -local function badhandler(msg) error( 'from bad handler' ) end -print( 'xpcall(error,goodhandler)', ( xpcall(error,goodhandler) ) ) -print( 'xpcall(goodfunction,goodhandler)', ( xpcall(goodfunction,goodhandler) ) ) -print( 'xpcall(badfunction,goodhandler)', ( xpcall(badfunction,goodhandler) ) ) -print( 'xpcall(goodfunction,badhandler)', ( xpcall(goodfunction,badhandler) ) ) -print( 'xpcall(badfunction,badhandler)', ( xpcall(badfunction,badhandler) ) ) -print( 'xpcall(goodfunction,nil)', ( xpcall(goodfunction,nil) ) ) -print( 'xpcall(badfunction,nil)', ( xpcall(badfunction,nil) ) ) -print( 'xpcall(goodfunction)', ( pcall( function() return xpcall(goodfunction) end ) ) ) -print( 'xpcall(badfunction)', ( pcall( function() return xpcall(badfunction) end ) ) ) - diff --git a/src/test/res/print.lua b/src/test/res/print.lua deleted file mode 100644 index 664ecd5b..00000000 --- a/src/test/res/print.lua +++ /dev/null @@ -1,26 +0,0 @@ --- print uses tostring under-the-hood! - -local function f() - print() - print('abc') - print(123) - print(true) - print('abc',123,true) -end - -local function g() - local fenv = {tostring=function(x) - return '*'..type(x)..'*' - end} - package.seeall(fenv) - f() - print('setfenv', pcall(setfenv, 0, fenv), {}, f ) - f() -end - -local s,c = pcall( coroutine.create, g ) -print('create', s, s and type(c) or c) -print('resume', pcall( coroutine.resume, c ) ) -f() - - diff --git a/src/test/res/req/subsample.lua b/src/test/res/req/subsample.lua deleted file mode 100644 index a53ed885..00000000 --- a/src/test/res/req/subsample.lua +++ /dev/null @@ -1,16 +0,0 @@ --- helper file for require() tests -require 'ids' -print( 'in subsample (before module statement)' ) -print( 'env', id(getfenv()), '_G', id(_G), '_NAME', _NAME, '_M', id(_M), '_PACKAGE', _PACKAGE ) -module( 'req.subsample', package.seeall ) - -print( 'in subsample (after module statement)' ) -print( 'env', id(getfenv()), '_G', id(_G), '_NAME', _NAME, '_M', id(_M), '_PACKAGE', _PACKAGE ) -function h() - print 'in subsample.h' - print( 'env', id(getfenv()), '_G', id(_G), '_NAME', _NAME, '_M', id(_M), '_PACKAGE', _PACKAGE ) -end -print 'loading subsample.lua' -h() -return 'return value from subsample', 'second return value from subsample' - diff --git a/src/test/res/require.lua b/src/test/res/require.lua deleted file mode 100644 index f7fd6dd0..00000000 --- a/src/test/res/require.lua +++ /dev/null @@ -1,101 +0,0 @@ --- unit tests for require() function -package.path = "?.lua;src/test/res/?.lua" -require 'ids' - --- tests on require -package.path='?.lua;src/test/res/?.lua' -function f( name ) - print( module( 'testmod', package.seeall ) ) - print( 'before', id(sample), id(bogus), id(_G[name]) ); - local status,result = pcall( require, name ) - if status then - print( 'pcall(require,"'..name..'")', status, id(result) ) - print( 'after', id(sample), id(bogus), id(_G[name]) ); - else - print( 'pcall(require,"'..name..'")', status ) - end -end -f('sample') -print( 'main', id(sample), id(bogus), id(custom), id(req) ); -f('sample') -print( 'main', id(sample), id(bogus), id(custom), id(req) ); -f('bogus') -print( 'main', id(sample), id(bogus), id(custom), id(req) ); -f( 'req.subsample' ) -print( 'main', id(sample), id(bogus), id(custom), id(req) ); - --- custom loader chain -local pl = package.loaders -for i=1,3 do - print( i,id(package.loaders[i]) ) -end -function loader1( ... ) - print ('in loader1', ...) - return "loader1 didn't find anything" -end -function loader2( name, ... ) - print ('in loader2', ...) - if name ~= 'custom' then - message = "name is not 'custom'" - print ('loader2 is returning', message ) - return message - end - table = {} - result = function() - print( 'in loader function, returning', id(table) ) - return table - end - print ('loader2 is returning', id(result) ) - return result -end -function loader3( ... ) - print ('in loader3', ...) - return nil -end -package.loaders = { loader1, loader2, loader3 } -f( 'bogus' ) -print( 'main', id(sample), id(bogus), id(custom), id(src) ); -f( 'custom' ) -print( 'main', id(sample), id(bogus), id(custom), id(src) ); - --- good, and bad lua samples -function g(name) - print( name, pcall(f,name) ) -end -package.loaders = { function(...) - print( 'in success loader', ... ) - return function(...) - print( 'in success chunk', ... ) - end -end } -pcall( g, 'require-sample-succeed' ) -package.loaders = { function(...) - print( 'in loader-error loader', ... ) - error( 'sample error thrown by loader-error loader') - return function(...) - print( 'in loader-error chunk', ... ) - end -end } -pcall( g, 'require-sample-loader-error' ) -package.loaders = { function(...) - print( 'in chunk-error loader', ... ) - return function(...) - error( 'sample error thrown by chunk-error function') - print( 'in chunk-error chunk', ... ) - end -end } -pcall( g, 'require-sample-chunk-error' ) - --- good, and bad java samples ---[[ (needs to be moved to different test suite) -package.loaders = pl -function g(name) - print( name, pcall(f,name) ) - print( 'main', id(org) ); -end -pcall( g, 'org.luaj.vm.require.RequireSampleClassCastExcep') -pcall( g, 'org.luaj.vm.require.RequireSampleLoadLuaError') -pcall( g, 'org.luaj.vm.require.RequireSampleLoadRuntimeExcep') -pcall( g, 'org.luaj.vm.require.RequireSampleSuccess') -pcall( g, 'org.luaj.vm.require.RequireSampleSuccess') ---]] \ No newline at end of file diff --git a/src/test/res/sample.lua b/src/test/res/sample.lua deleted file mode 100644 index 712560f7..00000000 --- a/src/test/res/sample.lua +++ /dev/null @@ -1,7 +0,0 @@ --- helper file for require() tests -module( 'sample', package.seeall ) -function h() - print 'in sample.h' -end -print 'loading sample.lua' - diff --git a/src/test/res/select.lua b/src/test/res/select.lua deleted file mode 100644 index 86c0abe6..00000000 --- a/src/test/res/select.lua +++ /dev/null @@ -1,31 +0,0 @@ --- Parts of this test are commented out because it looks like --- there is a problem with our argument passing, particularly in the --- presence of the VARARG instruction. - ---[[ local function f(...) -print("arg count:", select('#', ...)) -end - -local function g(...) - local a, b, c = select(2, ...) - print(a, b, c) -end -]]-- - -print((select(1, "a", "b", "c"))) -print( select(1, "a", "b", "c")) - -print((select(2, "a", "b", "c"))) -print( select(2, "a", "b", "c")) - -print((select(3, "a", "b", "c"))) -print( select(3, "a", "b", "c")) - -print((select(4, "a", "b", "c"))) -print( select(4, "a", "b", "c")) - -print( select("#") ) -print( select("#", "a") ) -print( select("#", "a", "b") ) --- f("hello", "world") --- g(1, 2, 3, 4, 5, 6, 7) diff --git a/src/test/res/setfenv.lua b/src/test/res/setfenv.lua deleted file mode 100644 index 492c2b46..00000000 --- a/src/test/res/setfenv.lua +++ /dev/null @@ -1,61 +0,0 @@ --- object ids -package.path = "?.lua;src/test/res/?.lua" -require 'ids' - -local id = id -local setfenv = setfenv -local print = print -local pcall = pcall -local create = coroutine.create -local resume = coroutine.resume -local seeall = package.seeall - --- unit tests for getfenv, setfenv -local function f3(level,value) - if value then - local t = {abc=value} - seeall(t) - setfenv( level, t ) - end - return abc -end -local function f2(...) - local r = f3(...) - return abc,r -end -local function f1(...) - local r,s = f2(...) - print( ' ....... f1 returning ',abc,r,s ) - return abc,r,s -end -local function survey(msg) - print('-------',msg) - print( ' _G,f1,f2,f3', id(_G),id(f1),id(f2),id(f3) ) - print( ' envs._G,f1,f2,f3', id(getfenv()),id(getfenv(f1)),id(getfenv(f2)),id(getfenv(f3)) ) - print( ' vals._G,f1,f2,f3', abc,getfenv(f1).abc, getfenv(f2).abc, getfenv(f3).abc ) - print( ' pcall(f1)', pcall(f1) ) -end - -survey( 'before') -setfenv(f1,{abc='ghi'}) -setfenv(f2,{abc='jkl'}) -setfenv(f3,{abc='mno'}) -survey( 'after') -print( 'abc,f1(1,"pqr")', abc,f1(1,"pqr") ) -print( 'abc,f1(2,"stu")', abc,f1(2,"stu") ) -print( 'abc,f1(3,"vwx")', abc,f1(3,"vwx") ) -survey( 'via f1()' ) - -local c = create( function() - survey( 'coroutine-thread-before') - print( 'f1(3,"abc")', f1(3,"567") ) - survey( 'coroutine-thread-1') - print( 'f1(2,"abc")', f1(2,"456") ) - survey( 'coroutine-thread-2') - print( 'f1(1,"abc")', f1(1,"345") ) - survey( 'coroutine-thread-3') - print( 'f1(0,"abc")', f1(0,"234") ) - survey( 'coroutine-thread-after') -end ) -print( 'resume', resume(c) ) -survey( 'post-resume') diff --git a/src/test/res/setlist.lua b/src/test/res/setlist.lua deleted file mode 100644 index 2a9ebbce..00000000 --- a/src/test/res/setlist.lua +++ /dev/null @@ -1,27 +0,0 @@ --- This file attemps to test that the setlist instruction works - -local list = { 1, 2, 3 } - --- for now, can't just do: --- for x, y in pairs( list ) do --- since our tables don't iterate over keys in the same order --- as regular Lua. - -print( #list ) -for i = 1, 3 do - print("list[", i, "]=", list[i]) -end - -local function printList( l ) - for i = 1, #l do - print(i, "->", l[i] ) - end -end - -printList( { "a", "b", "c" } ) - -local function foo() - return "d", "e", "f", "g" -end - -printList( { foo() } ) diff --git a/src/test/res/simplemetatables.lua b/src/test/res/simplemetatables.lua deleted file mode 100644 index 0a9c05e1..00000000 --- a/src/test/res/simplemetatables.lua +++ /dev/null @@ -1,14 +0,0 @@ --- The purpose of this test case is to check --- that certain simple metatable operations work properly -t = { b='bbb' } -t.__index = t -u = {} -setmetatable( u, t ) -u.c = 'ccc' - -print( 't.a', t.a ) -print( 'u.a', u.a ) -print( 't.b', t.b ) -print( 'u.b', u.b ) -print( 't.c', t.c ) -print( 'u.c', u.c ) diff --git a/src/test/res/sort.lua b/src/test/res/sort.lua deleted file mode 100644 index 39fc2b51..00000000 --- a/src/test/res/sort.lua +++ /dev/null @@ -1,27 +0,0 @@ --- concat -print( '-- sort tests' ) -local function tryall(cmp) - local function try(t) - print( table.concat(t,'-') ) - if pcall( table.sort, t, cmp ) then - print( table.concat(t,'-') ) - else - print( 'sort failed' ) - end - end - try{ 2, 4, 6, 8, 1, 3, 5, 7 } - try{ 333, 222, 111 } - try{ "www", "xxx", "yyy", "aaa", "bbb", "ccc" } - try{ 21, 23, "25", 27, 22, "24", 26, 28 } -end -local function comparator(a,b) - return tonumber(a)10 then break end -- exit the loop if the condition is true -end - -for count = 336,330,-2 do print(count) end -- numerical iteration - -function sum(a,b,c,d) -- "sum" method - local d = d or 0 - return a+b+c+d -- return sum -end -print( sum( 1, 2, 3, 4 ) ) -print( sum( 5, 6, 7 ) ) -print( sum( 9, 10, 11, 12, 13, 14 ) ) -print( sum( sum(1,2,3,4), sum(5,6,7), sum(9,10,11,12,13,14), 15 ) ) - - -function f0() print( "f0:" ) end -function f1(a) print( "f1:", a ) end -function f2(a,b) print( "f2:", a, b ) end -function f3(a,b,c) print( "f3:", a, b, c ) end -function f4(a,b,c,d) print( "f4:", a, b, c, d ) end - -f0() f0( "a1/1" ) f0( "a1/2", "a2/2" ) f0( "a1/3", "a2/3", "a3/3" ) f0( "a1/4", "a2/4", "a3/4", "a4/4" ) -f1() f1( "a1/1" ) f1( "a1/2", "a2/2" ) f1( "a1/3", "a2/3", "a3/3" ) f1( "a1/4", "a2/4", "a3/4", "a4/4" ) -f2() f2( "a1/1" ) f2( "a1/2", "a2/2" ) f2( "a1/3", "a2/3", "a3/3" ) f2( "a1/4", "a2/4", "a3/4", "a4/4" ) -f3() f3( "a1/1" ) f3( "a1/2", "a2/2" ) f3( "a1/3", "a2/3", "a3/3" ) f3( "a1/4", "a2/4", "a3/4", "a4/4" ) -f4() f4( "a1/1" ) f4( "a1/2", "a2/2" ) f4( "a1/3", "a2/3", "a3/3" ) f4( "a1/4", "a2/4", "a3/4", "a4/4" ) - -function g0(a,b,c,d) return end -function g1(a,b,c,d) return d end -function g2(a,b,c,d) return c, d end -function g3(a,b,c,d) return b, c, d end -function g4(a,b,c,d) return a, b, c, d end - -z = g0("c0.1/4", "c0.2/4", "c0.3/4", "c0.4/4") -print( "z0:", z ) -z = g2("c2.1/4", "c2.2/4", "c2.3/4", "c2.4/4") -print( "z2:", z ) -z = g4("c4.1/4", "c4.2/4", "c4.3/4", "c4.4/4") -print( "z4:", z ) - -a,b,c,d = g0( "c0.1/4", "c0.2/4", "c0.3/4", "c0.4/4" ) -print( "g0:", a, b, c, d, "(eol)" ) -a,b,c,d = g2( "b2.1/4", "b2.2/4", "b2.3/4", "b2.4/4" ) -print( "g2:", a, b, c, d, "(eol)" ) -a,b,c,d = g4( "b4.1/4", "b4.2/4", "b4.3/4", "b4.4/4" ) -print( "g4:", a, b, c, d, "(eol)" ) - -function func(a,b,c) - return a, b, c -end - -print( func(11, 12, 13) ) -print( func(23, 22, 21) ) -print( func(func(32,33,34), func(45,46,47), func(58,59,50)) ) - ---[[ -function p(a,...) - print("a",a) - print("...",...) - print("...,a",...,a) - print("a,...",a,...) -end -p() -p("q") -p("q","r") -p("q","r","s") ---]] - - -end \ No newline at end of file diff --git a/src/test/res/test2.lua b/src/test/res/test2.lua deleted file mode 100644 index 3993cbe2..00000000 --- a/src/test/res/test2.lua +++ /dev/null @@ -1,80 +0,0 @@ -function sum(a,b,c,d) -- "sum" method - local d = d or 0 - return a+b+c+d -- return sum -end -print( sum( 1, 2, 3, 4 ) ) -print( sum( 5, 6, 7 ) ) -print( sum( 9, 10, 11, 12, 13, 14 ) ) -print( sum( sum(1,2,3,4), sum(5,6,7), sum(9,10,11,12,13,14), 15 ) ) - -function myfunc(x) - return x*x; -end - -print( myfunc(0.25) ) - -do - local oldMyfunc = myfunc - local k = 55 - myfunc = function (x) - local a = k + oldMyfunc(x) - k = k + 5 - return a - end -end - -print( myfunc(0.1) ) -print( myfunc(0.1) ) - -i = 1 -table = { "west", "south", "east", "north" } -function next() - if ( i >= 4 ) then - i = 0 - end - i = i + 1 - return table[i] -end - -print( next() ) -print( next() ) -print( next() ) -print( next() ) -print( next() ) - -function room1 () - local move = next() - print( "room1 moving", move ) - if move == "south" then return room3() - elseif move == "east" then return room2() - else print("invalid move") - return room1() -- stay in the same room - end -end - -function room2 () - local move = next() - print( "room2 moving", move ) - if move == "south" then return room4() - elseif move == "west" then return room1() - else print("invalid move") - return room2() - end -end - -function room3 () - local move = next() - print( "room3 moving", move ) - if move == "north" then return room1() - elseif move == "east" then return room4() - else print("invalid move") - return room3() - end -end - -function room4 () - print("congratulations!") -end - -room1() - \ No newline at end of file diff --git a/src/test/res/test3.lua b/src/test/res/test3.lua deleted file mode 100644 index 89b9b29d..00000000 --- a/src/test/res/test3.lua +++ /dev/null @@ -1,62 +0,0 @@ - -function f0() print( "f0:" ) end -function f1(a) print( "f1:", a ) end -function f2(a,b) print( "f2:", a, b ) end -function f3(a,b,c) print( "f3:", a, b, c ) end -function f4(a,b,c,d) print( "f4:", a, b, c, d ) end - -f0() f0( "a1/1" ) f0( "a1/2", "a2/2" ) f0( "a1/3", "a2/3", "a3/3" ) f0( "a1/4", "a2/4", "a3/4", "a4/4" ) -f1() f1( "a1/1" ) f1( "a1/2", "a2/2" ) f1( "a1/3", "a2/3", "a3/3" ) f1( "a1/4", "a2/4", "a3/4", "a4/4" ) -f2() f2( "a1/1" ) f2( "a1/2", "a2/2" ) f2( "a1/3", "a2/3", "a3/3" ) f2( "a1/4", "a2/4", "a3/4", "a4/4" ) -f3() f3( "a1/1" ) f3( "a1/2", "a2/2" ) f3( "a1/3", "a2/3", "a3/3" ) f3( "a1/4", "a2/4", "a3/4", "a4/4" ) -f4() f4( "a1/1" ) f4( "a1/2", "a2/2" ) f4( "a1/3", "a2/3", "a3/3" ) f4( "a1/4", "a2/4", "a3/4", "a4/4" ) - -function g0(a,b,c,d) return end -function g1(a,b,c,d) return d end -function g2(a,b,c,d) return c, d end -function g3(a,b,c,d) return b, c, d end -function g4(a,b,c,d) return a, b, c, d end - -z = g0("c0.1/4", "c0.2/4", "c0.3/4", "c0.4/4") -print( "z0:", z ) -z = g2("c2.1/4", "c2.2/4", "c2.3/4", "c2.4/4") -print( "z2:", z ) -z = g4("c4.1/4", "c4.2/4", "c4.3/4", "c4.4/4") -print( "z4:", z ) - -a,b,c,d = g0( "c0.1/4", "c0.2/4", "c0.3/4", "c0.4/4" ) -print( "g0:", a, b, c, d, "(eol)" ) -a,b,c,d = g2( "b2.1/4", "b2.2/4", "b2.3/4", "b2.4/4" ) -print( "g2:", a, b, c, d, "(eol)" ) -a,b,c,d = g4( "b4.1/4", "b4.2/4", "b4.3/4", "b4.4/4" ) -print( "g4:", a, b, c, d, "(eol)" ) - -function func(a,b,c) - return a, b, c -end - -print( func(11, 12, 13) ) -print( func(23, 22, 21) ) -print( func(func(32,33,34), func(45,46,47), func(58,59,50)) ) - -function p(a,...) - print("a",a) - print("...",...) - print("...,a",...,a) - print("a,...",a,...) -end -p() -p("q") -p("q","r") -p("q","r","s") - -function first(...) - return 'abc' -end - -function second( a, b, c ) - return first( a, b, c ) -end - -print( 'second', second() ) - diff --git a/src/test/res/test4.lua b/src/test/res/test4.lua deleted file mode 100644 index ef651b51..00000000 --- a/src/test/res/test4.lua +++ /dev/null @@ -1,8 +0,0 @@ -function Point(x, y) -- "Point" object constructor - return { x = x, y = y } -- Creates and returns a new object (table) -end -array = { Point(10, 20), Point(30, 40), Point(50, 60) } -- Creates array of points -print(array[2].y) -- Prints 40 - - - diff --git a/src/test/res/test5.lua b/src/test/res/test5.lua deleted file mode 100644 index 372b0da1..00000000 --- a/src/test/res/test5.lua +++ /dev/null @@ -1,20 +0,0 @@ - -i = 777 -while i<780 do - print(i) - i = i+1 -end - -a,b = 0,1 -while true do -- infinite loop - print( b ) - a,b = b,a+b - if a>10 then break end -- exit the loop if the condition is true -end - -for count = 336,330,-2 do print(count) end -- numerical iteration - -for key,value in pairs({a=10, 3.14159265358, c="banana" }) -do - print(key, value) -end diff --git a/src/test/res/test6.lua b/src/test/res/test6.lua deleted file mode 100644 index 61ed1001..00000000 --- a/src/test/res/test6.lua +++ /dev/null @@ -1,99 +0,0 @@ -package.path = "?.lua;src/test/res/?.lua" -require 'ids' - -t = { 11, 22, 33, you='one', me='two' } - -print( "---------" ) -for a,b in pairs(t) do - print( id(a), id(b) ) -end -print( "----" ) -print( "t[2]", t[2] ) -print( "t.me", t.me ) -print( "t.fred", t.fred ) -print( "t['me']", t["me"] ) -print( "t['fred']", t["fred"] ) -print( "me", me ) -print( "fred", fred ) -print( "t[me]", t[me] ) -print( "t[fred]", t[fred] ) -function out(t,...) - print(type(t),...) -end --- basic metatable setting -t = { 11, 22, 33, you='one', me='two' } -mt = { __index = out, __newindex = out } -setmetatable(t,mt) -a = t[11] -b = t.one -c = t[1] -d = t.you -t[4] = 'rat' -t[1] = 'pipe' -print( a, b, c, d ) -print( "---------" ) -for a,b in pairs(t) do - print( id(a), id(b) ) -end -print( "----" ) - --- delegate to actual metatable -s = { } -mt = { __newindex = s, __index = _G } -setmetatable(t, mt) -print( t.you ) -x = 'wow' -print( t.x ) -me = 'here' -print( t.me ) -t[5] = 99 -print( "---------" ) -for a,b in pairs(s) do - print( id(a), id(b) ) -end -print( "----" ) - -Vector = {} -Vector_mt = { __index = Vector } - -function Vector:new(x,y) - return setmetatable( {x=x, y=y}, Vector_mt) -end - -function Vector:mag() - return math.sqrt(self:dot(self)) - end - -function Vector:dot(v) - return self.x * v.x + self.y * v.y -end - -v1 = Vector:new(3,4) -print( "---------" ) -for a,b in pairs(v1) do - print( id(a), id(b) ) -end - -print( "----" ) - -v2 = Vector:new(2,1) -print( v2:dot(v1) ) - -print( id(Vector) ) - -print( "=======" ) -for a,b in spairs(Vector) do - print( id(a), id(b) ) -end -print( "----" ) - -print( id(v1), id(v2) ) - -print( id(Vector_mt), id(getmetatable(v1)), id(getmetatable(v2)) ) - -print( "---------" ) -for a,b in pairs(Vector_mt) do - print( id(a), id(b) ) -end -print( "----" ) - diff --git a/src/test/res/test7-expected.out b/src/test/res/test7-expected.out deleted file mode 100644 index a8f9d418..00000000 --- a/src/test/res/test7-expected.out +++ /dev/null @@ -1,7 +0,0 @@ -java.lang.Object@xxxxxx -org.luaj.sample.SampleClass@xxxxxx -Hello -Hello -true -World -Square root of 9 is 3 diff --git a/src/test/res/test7.lua b/src/test/res/test7.lua deleted file mode 100644 index c0597fc5..00000000 --- a/src/test/res/test7.lua +++ /dev/null @@ -1,21 +0,0 @@ -local function fixhash(msg) - return (string.gsub(msg, "@(%x+)", function(s) return "@"..(string.rep("x", 6)) end)) -end - -obj = luajava.newInstance("java.lang.Object") -print( fixhash( tostring(obj) ) ) - -sample = luajava.newInstance("org.luaj.sample.SampleClass") -print( fixhash( tostring(sample) ) ) -sample.s = "Hello" -print( sample.s ) -print( sample:getS() ) - -sample:setObj(obj) -print( obj == sample:getObj() ) - -sample:setS( "World" ) -print( sample.s ) - -math = luajava.bindClass("java.lang.Math") -print("Square root of 9 is", math:sqrt(9.0)) diff --git a/src/test/res/test8.lua b/src/test/res/test8.lua deleted file mode 100644 index 77318f6b..00000000 --- a/src/test/res/test8.lua +++ /dev/null @@ -1,12 +0,0 @@ -t = {} -t[1] = "foo" -t[2] = "bah" -print(t[1]) -print(t[2]) -print(t[3]) - -t[1] = nil -t[2] = nil -print(t[1]) -print(t[2]) -print(t[3]) diff --git a/src/test/res/test9.lua b/src/test/res/test9.lua deleted file mode 100644 index effd1c77..00000000 --- a/src/test/res/test9.lua +++ /dev/null @@ -1,15 +0,0 @@ -local x - -local function g() - local a, b, c - return a, b, c -end - -local function f() - print("hello") -end - -g() -x = ... - -f() diff --git a/src/test/res/testfloat.lua b/src/test/res/testfloat.lua deleted file mode 100644 index 230864df..00000000 --- a/src/test/res/testfloat.lua +++ /dev/null @@ -1,5 +0,0 @@ -local f = luajava.bindClass("java.lang.Float") -print(f:toHexString(0.5)) -print(f:valueOf(0.5)) -print(f:valueOf("0.5")) - diff --git a/src/test/res/type.lua b/src/test/res/type.lua deleted file mode 100644 index 1619c3c4..00000000 --- a/src/test/res/type.lua +++ /dev/null @@ -1,8 +0,0 @@ -print(type(5)) -print(type(3.14)) -print(type("hello")) -print(type(function() return 1 end)) -print(type({})) -print(type(nil)) -print(type(2 < 5)) -print(type(pairs({}))) diff --git a/src/test/res/upvalues.lua b/src/test/res/upvalues.lua deleted file mode 100644 index ea760070..00000000 --- a/src/test/res/upvalues.lua +++ /dev/null @@ -1,25 +0,0 @@ -function test() - local x = 5 - function f() - x = x + 1 - return x - end - function g() - x = x - 1 - return x - end - print(f()) - print(g()) - return f, g -end - -f1, g1 = test() -print("f1()=", f1()) -print("g1()=", g1()) - -f2, g2 = test() -print("f2()=", f2()) -print("g2()=", g2()) - -print("g1()=", g1()) -print("f1()=", f1()) diff --git a/src/test/res/upvalues2.lua b/src/test/res/upvalues2.lua deleted file mode 100644 index f1c667d9..00000000 --- a/src/test/res/upvalues2.lua +++ /dev/null @@ -1,42 +0,0 @@ --- The point of this test is that when an upvalue is created, it may --- need to be inserted in the middle of the list, rather than always --- appended at the end. Otherwise, it may not be found when it is --- needed by another closure. - -local function test() - local x = 3 - local y = 5 - local z = 7 - - local function f() - print("y=", y) - end - - local function g() - print("z=", z) - end - - local function h() - print("x=", x) - end - - local function setter(x1, y1, z1) - x = x1 - y = y1 - z = z1 - end - - return f, g, h, setter -end - -local f, g, h, setter = test() - -h() -f() -g() - -setter("x", "y", "z") - -h() -f() -g() diff --git a/src/test/res/upvalues3.lua b/src/test/res/upvalues3.lua deleted file mode 100644 index 2e8e2c03..00000000 --- a/src/test/res/upvalues3.lua +++ /dev/null @@ -1,14 +0,0 @@ -local f - -do - local x = 10 - function g() - print(x, f()) - end -end - -function f() - return 20 -end - -g() diff --git a/src/test/res/varargs.lua b/src/test/res/varargs.lua deleted file mode 100644 index 3be8b527..00000000 --- a/src/test/res/varargs.lua +++ /dev/null @@ -1,51 +0,0 @@ - -function p(a,...) - print("a",a) - print("...",...) - print("...,a",...,a) - print("a,...",a,...) -end -function q(a,...) - print("a,arg[1],arg[2],arg[3]",a,arg.n,arg[1],arg[2],arg[3]) -end -function r(a,...) - print("a,arg",a,arg) - print("a",a) - print("...",...) - print("...,a",...,a) - print("a,...",a,...) -end -function s(a) - local arg = { '1', '2', '3' } - print("a,arg[1],arg[2],arg[3]",a,arg[1],arg[2],arg[3]) - print("a",a) -end -function t(a,...) - local arg = { '1', '2', '3' } - print("a,arg[1],arg[2],arg[3]",a,arg[1],arg[2],arg[3]) - print("a",a) - print("...",...) - print("...,a",...,a) - print("a,...",a,...) -end -function u(arg) - print( 'arg', arg ) -end -arg = { "global-1", "global-2", "global-3" } -function tryall(f,name) - print( '---- function '..name..'()' ) - print( '--'..name..'():' ) - print( ' ->', pcall( f ) ) - print( '--'..name..'("q"):' ) - print( ' ->', pcall( f, "q" ) ) - print( '--'..name..'("q","r"):' ) - print( ' ->', pcall( f, "q", "r" ) ) - print( '--'..name..'("q","r","s"):' ) - print( ' ->', pcall( f, "q", "r", "s" ) ) -end -tryall(p,'p') -tryall(q,'q') -tryall(r,'r') -tryall(s,'s') -tryall(t,'t') -tryall(u,'u') diff --git a/src/test/res/weaktable.lua b/src/test/res/weaktable.lua deleted file mode 100644 index 60a9140d..00000000 --- a/src/test/res/weaktable.lua +++ /dev/null @@ -1,150 +0,0 @@ - --- normalized printing -function eles(t,f) - f = f or pairs - all = {} - for k,v in f(t) do - if type(v) == 'table' then - v = '{'..tostring(v.v)..'}' - end - table.insert( all, "["..tostring(k).."]="..tostring(v) ) - end - table.sort( all ) - return "{"..table.concat(all,',').."}" -end - -function newtable(t) - return setmetatable(t,{__mode="v"}) -end - -function new(a) - return {v='_'..tostring(a).."_"} -end - --- basic weak-reference table test -local strong = { new('one'), new('two'), a=new('aaa'), c=new('ccc') } -local weak = newtable{ strong[1], new('three'), strong[2], new('four'), - a=new('aaa'), b=new('bbb'), c=new('ccc'), d=new('ddd') } -print( 'before, weak:', eles(weak) ) -print( 'before, strong:', eles(strong) ) -print( 'gc', pcall( collectgarbage, "collect" ) ) -print( 'after, weak:', eles(weak) ) -print( 'after, strong:', eles(strong) ) -print( 'gc', pcall( collectgarbage, "collect" ) ) -print( 'after, weak:', eles(weak) ) -print( 'after, strong:', eles(strong) ) - - - -print( '-- concat tests' ) -function tryconcat(t) - print( table.concat(t) ) - print( table.concat(t,'--') ) - print( table.concat(t,',',2) ) - print( table.concat(t,',',2,2) ) - print( table.concat(t,',',5,2) ) -end -tryconcat( newtable{ "one", "two", "three", a='aaa', b='bbb', c='ccc' } ) -tryconcat( newtable{ "one", "two", "three", "four", "five" } ) -function tryconcat(t) - print( table.concat(t) ) - print( table.concat(t,'--') ) - print( table.concat(t,',',2) ) -end -tryconcat( newtable{ a='aaa', b='bbb', c='ccc', d='ddd', e='eee' } ) -tryconcat( newtable{ [501]="one", [502]="two", [503]="three", [504]="four", [505]="five" } ) -tryconcat( newtable{} ) - --- insert, maxn -print( '-- insert, maxn tests' ) -local t = newtable{ "one", "two", "three", a='aaa', b='bbb', c='ccc' } -print( eles(t) ) -table.insert(t,'six'); print( eles(t) ) -table.insert(t,1,'seven'); print( eles(t) ) -table.insert(t,4,'eight'); print( eles(t) ) -table.insert(t,7,'nine'); print( eles(t) ) -table.insert(t,10,'ten'); print( eles(t) ) - --- remove -print( '-- remove tests' ) -t = newtable{ "one", "two", "three", "four", "five", "six", "seven", [10]="ten", a='aaa', b='bbb', c='ccc' } -print( eles(t) ) -print( 'table.remove(t)', table.remove(t) ); print( eles(t) ) -print( 'table.remove(t,1)', table.remove(t,1) ); print( eles(t) ) -print( 'table.remove(t,3)', table.remove(t,3) ); print( eles(t) ) -print( 'table.remove(t,5)', table.remove(t,5) ); print( eles(t) ) -print( 'table.remove(t,10)', table.remove(t,10) ); print( eles(t) ) -print( 'table.remove(t,-1)', table.remove(t,-1) ); print( eles(t) ) -print( 'table.remove(t,-1)', table.remove(t,-1) ) ; print( eles(t) ) - --- sort -print( '-- sort tests' ) -function sorttest(t,f) - t = (t) - print( table.concat(t,'-') ) - if f then - table.sort(t,f) - else - table.sort(t) - end - print( table.concat(t,'-') ) -end ---[[ -sorttest( newtable{ "one", "two", "three" } ) -sorttest( newtable{ "www", "vvv", "uuu", "ttt", "sss", "zzz", "yyy", "xxx" } ) -sorttest( newtable{ "www", "vvv", "uuu", "ttt", "sss", "zzz", "yyy", "xxx" }, function(a,b) return b