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+1) then { pc+=sBx; R(A+3)=R(A) }*/
- public static final int OP_FORPREP = 32; /* A sBx R(A)-=R(A+2); pc+=sBx */
-
- public static final int OP_TFORLOOP = 33; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
- if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
- public static final int OP_SETLIST = 34; /* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
-
- public static final int OP_CLOSE = 35; /* A close all variables in the stack up to (>=) 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;
-
-/**
- *
- *
- * 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_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;
- * 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:
- *
- *
- */
- 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:
- *
- *
- */
- 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.
- *
- * 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.
- *