diff --git a/src/core/org/luaj/lib/BaseLib.java b/src/core/org/luaj/lib/BaseLib.java index a43a1306..087a82c9 100644 --- a/src/core/org/luaj/lib/BaseLib.java +++ b/src/core/org/luaj/lib/BaseLib.java @@ -153,7 +153,7 @@ public class BaseLib extends LFunction { } case GETMETATABLE: { checkargexists(vm,2,Lua.LUA_TVALUE); - if ( 0 == vm.getmetatable(2) ) { + if ( ! vm.getmetatable(2) ) { vm.resettop(); vm.pushnil(); } else { @@ -248,14 +248,16 @@ public class BaseLib extends LFunction { vm.pushlvalue(t); } break; case GETFENV: { - if ( vm.gettop() <= 1 ) { - vm.pushlvalue(vm._G); - } else { - if ( ! vm.isfunction(2) ) { - int i = (vm.isnil(2)? 1: vm.tointeger(2)); - vm.pushlvalue( vm.getStackFrame(i).closure ); - } + if ( vm.isfunction(2) ) { vm.getfenv(-1); + } else { + int i = (vm.isnil(2)? 1: vm.tointeger(2)); + if ( i <= 0 ) + vm.pushlvalue(vm._G); + else if ( i-1 <= vm.cc ) + vm.pushlvalue( vm.getStackFrame(i-1).closure.env ); + else + vm.pushnil(); } vm.insert(1); vm.settop(1); diff --git a/src/core/org/luaj/lib/PackageLib.java b/src/core/org/luaj/lib/PackageLib.java index 9830fe28..35c40c40 100644 --- a/src/core/org/luaj/lib/PackageLib.java +++ b/src/core/org/luaj/lib/PackageLib.java @@ -24,12 +24,14 @@ package org.luaj.lib; import java.io.InputStream; import java.io.PrintStream; +import org.luaj.vm.CallInfo; import org.luaj.vm.LBoolean; 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; @@ -38,6 +40,13 @@ public class PackageLib extends LFunction { public static InputStream STDIN = null; public static PrintStream STDOUT = System.out; public static LTable LOADED = new LTable(); + + 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 String[] NAMES = { "package", @@ -51,7 +60,8 @@ public class PackageLib extends LFunction { 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 SEEALL = 4; + public static void install( LTable globals ) { for ( int i=1; 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 ) ); } diff --git a/src/core/org/luaj/vm/LuaState.java b/src/core/org/luaj/vm/LuaState.java index 49aa0ed0..bbb56289 100644 --- a/src/core/org/luaj/vm/LuaState.java +++ b/src/core/org/luaj/vm/LuaState.java @@ -1355,15 +1355,17 @@ public class LuaState extends Lua { *

* 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 0 and pushes nothing on the stack. + * metatable, the function returns false and pushes nothing on the stack. + * + * @return true if the metatable was pushed onto the stack, false otherwise */ - public int getmetatable(int index) { + public boolean getmetatable(int index) { LTable mt = topointer(index).luaGetMetatable(); if ( mt != null ) { pushlvalue( mt ); - return 1; + return true; } - return 0; + return false; } /** diff --git a/src/test/java/org/luaj/vm/LuaJTest.java b/src/test/java/org/luaj/vm/LuaJTest.java index eda119dd..d7e98023 100644 --- a/src/test/java/org/luaj/vm/LuaJTest.java +++ b/src/test/java/org/luaj/vm/LuaJTest.java @@ -13,7 +13,7 @@ import org.luaj.lib.j2se.LuajavaLib; public class LuaJTest extends TestCase { - + public void testTest1() throws IOException, InterruptedException { runTest( "test1" ); } @@ -78,6 +78,10 @@ public class LuaJTest extends TestCase { runTest( "metatables" ); } + public void testModule() throws IOException, InterruptedException { + runTest( "module" ); + } + public void testNext() throws IOException, InterruptedException { runTest( "next" ); } diff --git a/src/test/res/module.lua b/src/test/res/module.lua new file mode 100644 index 00000000..c25a49fe --- /dev/null +++ b/src/test/res/module.lua @@ -0,0 +1,63 @@ +-- unit tests for module() function +local ids = {} +local function id(obj) + if not obj or type(obj) == 'number' or type(obj) == 'string' then + return obj + end + local v = ids[obj] + if v then + return v + end + table.insert(ids,obj) + ids[obj] = type(obj)..'.'..tostring(#ids) + return ids[obj] +end + +-- module tests +local pr = print +local pkg = package +local g = _G +local md = module +local rq = require +local sa = package.seeall +local gfe = getfenv +local gmt = getmetatable +local function envs() + return id(gfe(0)), id(gfe(1)), id(gfe(2)), + id(gmt(gfe(0))), id(gmt(gfe(1))), id(gmt(gfe(2))) +end +local function trymodule(name) + pr( '_G['..name..']', id(g[name]) ) + pr( 'pkg.loaded['..name..']', id(pkg.loaded[name]) ) + pr( 'envs', envs() ) + md(name) + pr( 'envs', envs() ) + pr( 'status,result', status, result ) + pr( '_G['..name..']', id(g[name]) ) + local t = pkg.loaded[name] + pr( 't=pkg.loaded['..name..']', id(t) ) + pr( 't._M, t._NAME, t._PACKAGE', id(t._M), id(t._NAME), id(t._PACKAGE) ) + pr( 'rq('..name..')', id( rq(name) ) ) + pr( 'print', id(print) ) + pr( 'seeall(t)', sa(t) ) + pr( 'print, _G['..name..']', id(print), id(g[name]) ) +end +trymodule('abc.def.ghi') +trymodule('abc.def.ghi') +trymodule('abc.def') +trymodule('abc.def.lmn') +trymodule('abc.def') +trymodule('abc') +package.loaded['opq.rst'] = {} +trymodule('opq.rst') +trymodule('opq.rst') +uvw = { xyz="x1y1z1" } +--print( "uvw", id(uvw) ) +--print( "uvw.xyz", id(uvw.xyz) ) +--print( "uvw.abc", id(uvw.abc) ) +print( pcall( trymodule, 'uvw.xyz' ) ) +print( pcall( trymodule, 'uvw' ) ) +print( pcall( trymodule, 'uvw.abc' ) ) +print( "uvw", id(uvw) ) +print( "uvw.xyz", id(uvw.xyz) ) +print( "uvw.abc", id(uvw.abc) ) diff --git a/src/test/res/module.luac b/src/test/res/module.luac new file mode 100644 index 00000000..003d4253 Binary files /dev/null and b/src/test/res/module.luac differ