diff --git a/src/core/org/luaj/lib/PackageLib.java b/src/core/org/luaj/lib/PackageLib.java index b5740c6b..b8a0380b 100644 --- a/src/core/org/luaj/lib/PackageLib.java +++ b/src/core/org/luaj/lib/PackageLib.java @@ -195,8 +195,8 @@ public class PackageLib extends LFunction { /* check whether table already has a _NAME field */ - module.luaGetTable(vm, module, _NAME); - if ( vm.isnil(-1) ) { + LValue name = module.luaGetTable(vm, module, _NAME); + if ( name.isNil() ) { modinit( vm, module, modname ); } @@ -289,9 +289,10 @@ public class PackageLib extends LFunction { vm.settop(0); /* else must load it; iterate over available loaders */ - pckg.luaGetTable(vm, pckg, _LOADERS); - if ( ! vm.istable(1) ) + LValue val = pckg.luaGetTable(vm, pckg, _LOADERS); + if ( ! val.isTable() ) vm.error( "'package.loaders' must be a table" ); + vm.pushlvalue(val); Vector v = new Vector(); for ( int i=1; true; i++ ) { vm.rawgeti(1, i); @@ -330,15 +331,14 @@ public class PackageLib extends LFunction { private void loader_preload( LuaState vm ) { LString name = vm.tolstring(2); - pckg.luaGetTable(vm, pckg, _PRELOAD); - if ( ! vm.istable(-1) ) + LValue preload = pckg.luaGetTable(vm, pckg, _PRELOAD); + if ( ! preload.isTable() ) vm.error("package.preload '"+name+"' must be a table"); - LTable preload = vm.totable(-1); - preload.luaGetTable(vm, preload, name); - if ( vm.isnil(-1) ) + LValue val = preload.luaGetTable(vm, preload, name); + if ( val.isNil() ) vm.pushstring("\n\tno field package.preload['"+name+"']"); - vm.insert(1); - vm.settop(1); + vm.resettop(); + vm.pushlvalue(val); } private void loader_Lua( LuaState vm ) { @@ -372,10 +372,10 @@ public class PackageLib extends LFunction { private InputStream findfile(LuaState vm, String name, LString pname) { Platform p = Platform.getInstance(); - pckg.luaGetTable(vm, pckg, pname); - if ( ! vm.isstring(-1) ) + LValue pkg = pckg.luaGetTable(vm, pckg, pname); + if ( ! pkg.isString() ) vm.error("package."+pname+" must be a string"); - String path = vm.tostring(-1); + String path = pkg.toJavaString(); int e = -1; int n = path.length(); StringBuffer sb = null; diff --git a/src/core/org/luaj/lib/StringLib.java b/src/core/org/luaj/lib/StringLib.java index 1cfbe7c1..2f0ec521 100644 --- a/src/core/org/luaj/lib/StringLib.java +++ b/src/core/org/luaj/lib/StringLib.java @@ -667,7 +667,7 @@ public class StringLib extends LFunction { push_onecapture( 0, soffset, end ); LValue k = vm.topointer( -1 ); vm.pop( 1 ); - ((LTable) repl).luaGetTable( vm, repl, k ); + vm.pushlvalue( ((LTable) repl).luaGetTable( vm, repl, k ) ); } else { vm.error( "string/function/table expected" ); return; diff --git a/src/core/org/luaj/vm/LFunction.java b/src/core/org/luaj/vm/LFunction.java index c008f8b9..ea8d028f 100644 --- a/src/core/org/luaj/vm/LFunction.java +++ b/src/core/org/luaj/vm/LFunction.java @@ -37,11 +37,12 @@ public class LFunction extends LValue { vm.call( 3, 0 ); } - public void luaGetTable(LuaState vm, LValue table, LValue key) { + public LValue luaGetTable(LuaState vm, LValue table, LValue key) { vm.pushlvalue( this ); vm.pushlvalue( table ); vm.pushlvalue( key ); vm.call( 2, 1 ); + return vm.poplvalue(); } public int luaGetType() { diff --git a/src/core/org/luaj/vm/LString.java b/src/core/org/luaj/vm/LString.java index 0a278d87..ce38c6d8 100644 --- a/src/core/org/luaj/vm/LString.java +++ b/src/core/org/luaj/vm/LString.java @@ -163,7 +163,11 @@ public class LString extends LValue { public static LString newStringNoCopy(byte[] buf, int off, int len) { return new LString( buf, off, len ); } - + + public boolean isString() { + return true; + } + public boolean equals(Object o) { if ( o != null && o instanceof LString ) { LString s = (LString) o; diff --git a/src/core/org/luaj/vm/LTable.java b/src/core/org/luaj/vm/LTable.java index 192e8dd4..54b3fb98 100644 --- a/src/core/org/luaj/vm/LTable.java +++ b/src/core/org/luaj/vm/LTable.java @@ -77,6 +77,10 @@ public class LTable extends LValue { hashValues = new Object[nhash]; } + public boolean isTable() { + return true; + + } /** Get capacity of hash part */ public int getArrayCapacity() { return array.length; @@ -229,12 +233,12 @@ public class LTable extends LValue { } - public void luaGetTable(LuaState vm, LValue table, LValue key) { + public LValue luaGetTable(LuaState vm, LValue table, LValue key) { LValue v = get(key); if ( v.isNil() && m_metatable != null ) { - super.luaGetTable( vm, table, key ); + return super.luaGetTable( vm, table, key ); } else { - vm.pushlvalue(v); + return v; } } diff --git a/src/core/org/luaj/vm/LValue.java b/src/core/org/luaj/vm/LValue.java index 4c0952fa..aed88d7d 100644 --- a/src/core/org/luaj/vm/LValue.java +++ b/src/core/org/luaj/vm/LValue.java @@ -51,8 +51,9 @@ public class LValue { throw new LuaErrorException( "attempt to compare "+typea+" with "+typeb ); } - private void indexError(LuaState vm, LValue nontable) { + private LValue indexError(LuaState vm, LValue nontable) { vm.error( "attempt to index ? (a "+nontable.luaGetTypeName()+" value)", 1 ); + return LNil.NIL; } public String id() { @@ -146,17 +147,17 @@ public class LValue { * @param vm the calling vm * @param table the table from which to get the value * @param key the key to look up + * @return TODO */ - public void luaGetTable(LuaState vm, LValue table, LValue key) { + public LValue luaGetTable(LuaState vm, LValue table, LValue key) { LTable mt = luaGetMetatable(); if ( mt != null ) { LValue event = mt.get( TM_INDEX ); if ( event != null && ! event.isNil() ) { - event.luaGetTable( vm, table, key ); - return; + return event.luaGetTable( vm, table, key ); } } - indexError( vm, table ); + return indexError( vm, table ); } /** Get the value as a LString @@ -329,4 +330,14 @@ public class LValue { public void luaConcatTo(ByteArrayOutputStream baos) { throw new LuaErrorException( "attempt to concat ? (a "+luaGetTypeName()+" value)"); } + + /** Return true if this is a LString */ + public boolean isString() { + return false; + } + + /** Return true if this is a LTable */ + public boolean isTable() { + return false; + } } diff --git a/src/core/org/luaj/vm/LuaState.java b/src/core/org/luaj/vm/LuaState.java index 77e15abb..92939988 100644 --- a/src/core/org/luaj/vm/LuaState.java +++ b/src/core/org/luaj/vm/LuaState.java @@ -558,17 +558,17 @@ public class LuaState extends Lua { case LuaState.OP_GETGLOBAL: { b = LuaState.GETARG_Bx(i); key = k[b]; - table = cl.env; - top = base + a; - table.luaGetTable(this, table, key); + table = cl.env; + this.top = base + a; + this.stack[base+a] = table.luaGetTable(this, table, key); continue; } case LuaState.OP_GETTABLE: { b = LuaState.GETARG_B(i); key = GETARG_RKC(k, i); table = this.stack[base + b]; - top = base + a; - table.luaGetTable(this, table, key); + this.top = base + a; + this.stack[base+a] = table.luaGetTable(this, table, key); continue; } case LuaState.OP_SETGLOBAL: { @@ -576,6 +576,7 @@ public class LuaState extends Lua { key = k[b]; val = this.stack[base + a]; table = cl.env; + this.top = base + a; table.luaSetTable(this, table, key, val); continue; } @@ -588,6 +589,7 @@ public class LuaState extends Lua { key = GETARG_RKB(k, i); val = GETARG_RKC(k, i); table = this.stack[base + a]; + this.top = base + a; table.luaSetTable(this, table, key, val); continue; } @@ -600,8 +602,8 @@ public class LuaState extends Lua { case LuaState.OP_SELF: { rkb = GETARG_RKB(k, i); rkc = GETARG_RKC(k, i); - top = base + a; - rkb.luaGetTable(this, rkb, rkc); + this.top = base + a; + this.stack[base + a] = rkb.luaGetTable(this, rkb, rkc); this.stack[base + a + 1] = rkb; // StkId rb = RB(i); // setobjs2s(L, ra+1, rb); @@ -1327,7 +1329,7 @@ public class LuaState extends Lua { */ public void getfield(int index, LString k) { LTable t = totable(index); - t.luaGetTable(this, t, k); + pushlvalue( t.luaGetTable(this, t, k) ); } /** @@ -1344,7 +1346,7 @@ public class LuaState extends Lua { */ public void getglobal(String s) { LTable t = this._G; - t.luaGetTable(this, t, new LString(s)); + pushlvalue( t.luaGetTable(this, t, new LString(s)) ); } /** @@ -1385,7 +1387,7 @@ public class LuaState extends Lua { LValue k = poplvalue(); // todo: what if this triggers metatable ops // pushlvalue( t.luaGetTable(this, t, k) ); - t.luaGetTable(this, t, k); + pushlvalue( t.luaGetTable(this, t, k) ); } /** @@ -1518,7 +1520,7 @@ public class LuaState extends Lua { * number (which is always convertible to a string), and 0 otherwise. */ public boolean isstring(int index) { - return type(index) == Lua.LUA_TSTRING; + return topointer(index).isString(); } /** @@ -1529,7 +1531,7 @@ public class LuaState extends Lua { * 0 otherwise. */ public boolean istable(int index) { - return type(index) == Lua.LUA_TTABLE; + return topointer(index).isTable(); } /** diff --git a/src/j2se/org/luaj/lib/j2se/LuajavaLib.java b/src/j2se/org/luaj/lib/j2se/LuajavaLib.java index 6ca555fb..b1826014 100644 --- a/src/j2se/org/luaj/lib/j2se/LuajavaLib.java +++ b/src/j2se/org/luaj/lib/j2se/LuajavaLib.java @@ -144,15 +144,14 @@ public final class LuajavaLib extends LFunction { super(o); this.clazz = clazz; } - public void luaGetTable(LuaState vm, LValue table, LValue key) { + public LValue luaGetTable(LuaState vm, LValue table, LValue key) { final String s = key.toJavaString(); try { Field f = clazz.getField(s); Object o = f.get(m_instance); - LValue v = CoerceJavaToLua.coerce( o ); - vm.pushlvalue( v ); + return CoerceJavaToLua.coerce( o ); } catch (NoSuchFieldException nsfe) { - vm.pushlvalue( new LMethod(m_instance,clazz,s) ); + return new LMethod(m_instance,clazz,s); } catch (Exception e) { throw new LuaErrorException(e); } diff --git a/src/sample/org/luaj/sample/LuaJitRunner.java b/src/sample/org/luaj/sample/LuaJitRunner.java new file mode 100644 index 00000000..4a878232 --- /dev/null +++ b/src/sample/org/luaj/sample/LuaJitRunner.java @@ -0,0 +1,89 @@ +/******************************************************************************* +* Copyright (c) 2007 LuaJ. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +******************************************************************************/ +package org.luaj.sample; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.luaj.jit.LuaJit; +import org.luaj.platform.J2sePlatform; +import org.luaj.vm.LClosure; +import org.luaj.vm.LPrototype; +import org.luaj.vm.LValue; +import org.luaj.vm.LoadState; +import org.luaj.vm.LuaErrorException; +import org.luaj.vm.LuaState; +import org.luaj.vm.Platform; + + +/** + * Program to run a lua chunk + * + * @author jim_roseborough + */ +public class LuaJitRunner { + + public static void main( String[] args ) throws IOException { + + // new lua state + Platform.setInstance(new J2sePlatform()); + LuaState state = Platform.newLuaState(); + LuaJit.install(); + + // get script name + for ( int i=0; i