Skip to content

CallException: net.sandius.rembulan.lib.BadArgumentException: bad argument #1 to 'ipairs' (table expected, got light userdata) #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
JuKu opened this issue Oct 12, 2018 · 1 comment

Comments

@JuKu
Copy link

JuKu commented Oct 12, 2018

I get this exception:

net.sandius.rembulan.exec.CallException: net.sandius.rembulan.lib.BadArgumentException: bad argument #1 to 'ipairs' (table expected, got light userdata)

	at net.sandius.rembulan.exec.DirectCallExecutor$Result.get(DirectCallExecutor.java:184)
	at net.sandius.rembulan.exec.DirectCallExecutor.execute(DirectCallExecutor.java:310)
	at net.sandius.rembulan.exec.DirectCallExecutor.resume(DirectCallExecutor.java:252)
	at net.sandius.rembulan.exec.DirectCallExecutor.call(DirectCallExecutor.java:228)
	at com.jukusoft.mmo.engine.applayer.script.lua.LuaScriptEngine.execFunc(LuaScriptEngine.java:77)
	at com.jukusoft.mmo.engine.applayer.script.lua.LuaScriptEngineTest.testExecGlobalFunc(LuaScriptEngineTest.java:102)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: net.sandius.rembulan.lib.BadArgumentException: bad argument #1 to 'ipairs' (table expected, got light userdata)
	at net.sandius.rembulan.lib.impl.ArgumentIterator.badArgument(ArgumentIterator.java:117)
	at net.sandius.rembulan.lib.impl.ArgumentIterator.nextStrict(ArgumentIterator.java:181)
	at net.sandius.rembulan.lib.impl.ArgumentIterator.nextTable(ArgumentIterator.java:354)
	at net.sandius.rembulan.lib.impl.DefaultBasicLib$IPairs.invoke(DefaultBasicLib.java:380)
	at net.sandius.rembulan.lib.impl.AbstractLibFunction.invoke(AbstractLibFunction.java:36)
	at net.sandius.rembulan.runtime.AbstractFunctionAnyArg.invoke(AbstractFunctionAnyArg.java:31)
	at net.sandius.rembulan.runtime.Dispatch.mt_invoke(Dispatch.java:64)
	at net.sandius.rembulan.runtime.Dispatch.call(Dispatch.java:199)
	at engine0$0.run(script_add:3)
	at engine0$0.invoke(script_add)
	at net.sandius.rembulan.runtime.AbstractFunction1.invoke(AbstractFunction1.java:57)
	at net.sandius.rembulan.runtime.Dispatch.mt_invoke(Dispatch.java:95)
	at net.sandius.rembulan.runtime.Dispatch.call(Dispatch.java:402)
	at net.sandius.rembulan.runtime.Coroutine$BootstrapResumable.resume(Coroutine.java:89)
	at net.sandius.rembulan.runtime.ResumeInfo.resume(ResumeInfo.java:35)
	at net.sandius.rembulan.runtime.Call$Resumer.continueCurrentCoroutine(Call.java:513)
	at net.sandius.rembulan.runtime.Call$Resumer.resume(Call.java:537)
	at net.sandius.rembulan.runtime.Call.resume(Call.java:232)
	at net.sandius.rembulan.runtime.Call.access$000(Call.java:37)
	at net.sandius.rembulan.runtime.Call$CallContinuation.resume(Call.java:181)
	at net.sandius.rembulan.exec.DirectCallExecutor.execute(DirectCallExecutor.java:290)
	... 28 more

What does this exception means?

Source code:

public class LuaScriptEngine implements IScriptEngine {

    protected StateContext state = null;
    protected Table env = null;

    //map with all registered global lua functions
    protected ObjectObjectMap<String, LuaFunction> luaFunctions = new ObjectObjectHashMap<>();

    public LuaScriptEngine () {
        //initialize state
        this.state = StateContexts.newDefaultInstance();
        this.env = StandardLibrary.in(RuntimeEnvironments.system()).installInto(state);

        //register global functions
        this.env.rawset("logd", new LogDebugFunc());
        this.env.rawset("logi", new LogInfoFunc());

        this.env.rawset("now", new NowFunc());
    }

    /**
     * compile lua script as string to function
     *
     * //@param rootClassPrefix  the class name prefix for compiled classes, must not be {@code null}
     */
    @Override
    public void compile (String scriptName, String programStr) throws ScriptLoadException {
        Log.d("Scripts", "compile script '" + scriptName + "'");

        scriptName = "script_" + scriptName;

        //compile
        ChunkLoader loader = CompilerChunkLoader.of("engine");
        LuaFunction func = null;
        try {
            func = loader.loadTextChunk(new Variable(env), scriptName, programStr);
        } catch (LoaderException e) {
            Log.e("Scripts", "Couldn't compile lua script: " + programStr + ", error: " + e.getLuaStyleErrorMessage(), e);
            throw new ScriptLoadException("Coulnd't compile script: " + programStr + ", error: " + e.getLuaStyleErrorMessage());
        }

        this.luaFunctions.put(scriptName, func);
    }

    @Override
    public Object execFunc(String funcName, Object... args) throws CallException {
        // get a reference to the function
        LuaFunction func = (LuaFunction) env.rawget(funcName);

        if (func == null) {
            throw new NullPointerException("lua function cannot be null.");
        }

        try {
            Object[] objs = DirectCallExecutor.newExecutor().call(state, func, args);

            if (objs.length > 0) {
                return objs[0];
            } else {
                //it's a void method
                return null;
            }
        } catch (CallException e) {
            Log.w("Scripts", "CallException: ", e);
            throw e;
            //throw new ScriptExecutionException("CallException: " + e.getLocalizedMessage());
        } catch (CallPausedException e) {
            Log.w("Scripts", "CallPausedException: ", e);
        } catch (InterruptedException e) {
            Log.w("Scripts", "InterruptedException: ", e);
        }

        return null;
    }

    @Override
    public Object execFunc(String funcName) throws CallException {
        return this.execFunc(funcName, new Object[0]);
    }

    @Override
    public Object execScript(String scriptName, Object... args) {
        scriptName = "script_" + scriptName;

        LuaFunction func = this.luaFunctions.get(scriptName);

        if (func == null) {
            throw new IllegalStateException("lua script '" + scriptName + "' doesn't exists in cache, you have to compile it first!");
        }

        Log.d("Scripts", "execute lua script '" + scriptName + "'");

        try {
            Object[] objs = DirectCallExecutor.newExecutor().call(state, func);

            if (objs.length > 0) {
                return objs[0];
            } else {
                //it's a void method
                return null;
            }
        } catch (CallException e) {
            Log.w("Scripts", "CallException: ", e);
        } catch (CallPausedException e) {
            Log.w("Scripts", "CallPausedException: ", e);
        } catch (InterruptedException e) {
            Log.w("Scripts", "InterruptedException: ", e);
        }

        return null;
    }

    protected void printEnvDebug () {
        for (long i = 0; i < env.rawlen(); i++) {
            Log.d("Scripts", "rawget[" + i + "]: " + env.rawget(i));
        }
    }

}

Test method which throws this exception:

@Test
    public void testExecGlobalFunc () throws ScriptLoadException, CallException {
        GameTime time = GameTime.getInstance();
        time.setTime(System.currentTimeMillis());

        LuaScriptEngine engine = new LuaScriptEngine();
        engine.compile("add", "function add (a)\n" +
                "      local sum = 0\n" +
                "      for i,v in ipairs(a) do\n" +
                "        sum = sum + v\n" +
                "      end\n" +
                "      return sum\n" +
                "    end");
        engine.execScript("add");

        engine.printEnvDebug();

        assertEquals(6, engine.execFunc("add", new int[] {1, 2, 3}));
    }
@JuKu
Copy link
Author

JuKu commented Oct 12, 2018

I already have found the solution:
I have to use class Table instead of an array:

@Test
    public void testExecGlobalFunc () throws ScriptLoadException, CallException {
        GameTime time = GameTime.getInstance();
        time.setTime(System.currentTimeMillis());

        LuaScriptEngine engine = new LuaScriptEngine();
        engine.compile("add", "function add (a)\n" +
                "      local sum = 0\n" +
                "      for i,v in ipairs(a) do\n" +
                "        print(v);" +
                "        sum = sum + v\n" +
                "      end\n" +
                "      return sum\n" +
                "    end");
        engine.execScript("add");

        engine.printEnvDebug();

        Table table = new DefaultTable();
        table.rawset(1l, new Long(1));
        table.rawset(2l, new Long(2));
        table.rawset(3l, new Long(3));
        assertEquals(6l, engine.execFunc("add", table));
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant