mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-11-04 07:32:59 +00:00 
			
		
		
		
	Migrate LuaJLuaMachine to use Cobalt
This commit is contained in:
		@@ -15,7 +15,7 @@ import dan200.computercraft.core.apis.*;
 | 
				
			|||||||
import dan200.computercraft.core.filesystem.FileSystem;
 | 
					import dan200.computercraft.core.filesystem.FileSystem;
 | 
				
			||||||
import dan200.computercraft.core.filesystem.FileSystemException;
 | 
					import dan200.computercraft.core.filesystem.FileSystemException;
 | 
				
			||||||
import dan200.computercraft.core.lua.ILuaMachine;
 | 
					import dan200.computercraft.core.lua.ILuaMachine;
 | 
				
			||||||
import dan200.computercraft.core.lua.LuaJLuaMachine;
 | 
					import dan200.computercraft.core.lua.CobaltLuaMachine;
 | 
				
			||||||
import dan200.computercraft.core.terminal.Terminal;
 | 
					import dan200.computercraft.core.terminal.Terminal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
@@ -622,7 +622,7 @@ public class Computer
 | 
				
			|||||||
    private void initLua()
 | 
					    private void initLua()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Create the lua machine
 | 
					        // Create the lua machine
 | 
				
			||||||
        ILuaMachine machine = new LuaJLuaMachine( this );
 | 
					        ILuaMachine machine = new CobaltLuaMachine( this );
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // Add the APIs
 | 
					        // Add the APIs
 | 
				
			||||||
        for(ILuaAPI api : m_apis)
 | 
					        for(ILuaAPI api : m_apis)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,105 +15,102 @@ import dan200.computercraft.core.apis.ILuaAPI;
 | 
				
			|||||||
import dan200.computercraft.core.computer.Computer;
 | 
					import dan200.computercraft.core.computer.Computer;
 | 
				
			||||||
import dan200.computercraft.core.computer.ITask;
 | 
					import dan200.computercraft.core.computer.ITask;
 | 
				
			||||||
import dan200.computercraft.core.computer.MainThread;
 | 
					import dan200.computercraft.core.computer.MainThread;
 | 
				
			||||||
 | 
					import org.squiddev.cobalt.*;
 | 
				
			||||||
import org.luaj.vm2.*;
 | 
					import org.squiddev.cobalt.compiler.CompileException;
 | 
				
			||||||
import org.luaj.vm2.lib.OneArgFunction;
 | 
					import org.squiddev.cobalt.compiler.LoadState;
 | 
				
			||||||
import org.luaj.vm2.lib.VarArgFunction;
 | 
					import org.squiddev.cobalt.debug.DebugFrame;
 | 
				
			||||||
import org.luaj.vm2.lib.ZeroArgFunction;
 | 
					import org.squiddev.cobalt.debug.DebugHandler;
 | 
				
			||||||
import org.luaj.vm2.lib.jse.JsePlatform;
 | 
					import org.squiddev.cobalt.debug.DebugState;
 | 
				
			||||||
 | 
					import org.squiddev.cobalt.function.LuaFunction;
 | 
				
			||||||
 | 
					import org.squiddev.cobalt.function.VarArgFunction;
 | 
				
			||||||
 | 
					import org.squiddev.cobalt.lib.*;
 | 
				
			||||||
 | 
					import org.squiddev.cobalt.lib.platform.AbstractResourceManipulator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Nonnull;
 | 
					import javax.annotation.Nonnull;
 | 
				
			||||||
import java.io.*;
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.io.InputStream;
 | 
				
			||||||
 | 
					import java.io.OutputStream;
 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.IdentityHashMap;
 | 
					import java.util.IdentityHashMap;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class LuaJLuaMachine implements ILuaMachine
 | 
					import static org.squiddev.cobalt.Constants.NONE;
 | 
				
			||||||
 | 
					import static org.squiddev.cobalt.ValueFactory.valueOf;
 | 
				
			||||||
 | 
					import static org.squiddev.cobalt.ValueFactory.varargsOf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class CobaltLuaMachine implements ILuaMachine
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    private Computer m_computer;
 | 
					    private final Computer m_computer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private LuaValue m_globals;
 | 
					    private final LuaState m_state;
 | 
				
			||||||
    private LuaValue m_loadString;
 | 
					    private final LuaTable m_globals;
 | 
				
			||||||
    private LuaValue m_assert;
 | 
					 | 
				
			||||||
    private LuaValue m_coroutine_create;
 | 
					 | 
				
			||||||
    private LuaValue m_coroutine_resume;
 | 
					 | 
				
			||||||
    private LuaValue m_coroutine_yield;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private LuaValue m_mainRoutine;
 | 
					    private LuaThread m_mainRoutine;
 | 
				
			||||||
    private String m_eventFilter;
 | 
					    private String m_eventFilter;
 | 
				
			||||||
    private String m_softAbortMessage;
 | 
					    private String m_softAbortMessage;
 | 
				
			||||||
    private String m_hardAbortMessage;
 | 
					    private String m_hardAbortMessage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Map<Object, LuaValue> m_valuesInProgress;
 | 
					    public CobaltLuaMachine( Computer computer )
 | 
				
			||||||
    private Map<LuaValue, Object> m_objectsInProgress;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public LuaJLuaMachine( Computer computer )
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        m_computer = computer;
 | 
					        m_computer = computer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Create an environment to run in
 | 
					        // Create an environment to run in
 | 
				
			||||||
        m_globals = JsePlatform.debugGlobals();
 | 
					        final LuaState state = this.m_state = new LuaState( new AbstractResourceManipulator()
 | 
				
			||||||
        m_loadString = m_globals.get("loadstring");
 | 
					        {
 | 
				
			||||||
        m_assert = m_globals.get("assert");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        LuaValue coroutine = m_globals.get("coroutine");
 | 
					 | 
				
			||||||
        final LuaValue native_coroutine_create = coroutine.get("create");
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        LuaValue debug = m_globals.get("debug");
 | 
					 | 
				
			||||||
        final LuaValue debug_sethook = debug.get("sethook");
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        coroutine.set("create", new OneArgFunction() {
 | 
					 | 
				
			||||||
            @Override
 | 
					            @Override
 | 
				
			||||||
            public LuaValue call( LuaValue value )
 | 
					            public InputStream findResource( String filename )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                final LuaThread thread = native_coroutine_create.call( value ).checkthread();
 | 
					                return null;
 | 
				
			||||||
                debug_sethook.invoke( new LuaValue[] {
 | 
					 | 
				
			||||||
                    thread,
 | 
					 | 
				
			||||||
                    new ZeroArgFunction() {
 | 
					 | 
				
			||||||
                        @Override
 | 
					 | 
				
			||||||
                        public LuaValue call() {
 | 
					 | 
				
			||||||
                            String hardAbortMessage = m_hardAbortMessage;
 | 
					 | 
				
			||||||
                            if( hardAbortMessage != null )
 | 
					 | 
				
			||||||
                            {
 | 
					 | 
				
			||||||
                                LuaThread.yield(LuaValue.NIL);
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            return LuaValue.NIL;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                    LuaValue.NIL,
 | 
					 | 
				
			||||||
                    LuaValue.valueOf(100000)
 | 
					 | 
				
			||||||
                } );
 | 
					 | 
				
			||||||
                return thread;                
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        } );
 | 
				
			||||||
 | 
					        state.debug = new DebugHandler( state )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            private int count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        m_coroutine_create = coroutine.get("create");
 | 
					            @Override
 | 
				
			||||||
        m_coroutine_resume = coroutine.get("resume");
 | 
					            public void onInstruction( DebugState ds, DebugFrame di, int pc, Varargs extras, int top ) throws LuaError
 | 
				
			||||||
        m_coroutine_yield = coroutine.get("yield");
 | 
					            {
 | 
				
			||||||
 | 
					                int count = ++this.count;
 | 
				
			||||||
 | 
					                if( count > 100000 )
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if( m_hardAbortMessage != null ) LuaThread.yield( state, NONE );
 | 
				
			||||||
 | 
					                    this.count = 0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                super.onInstruction( ds, di, pc, extras, top );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @Override
 | 
				
			||||||
 | 
					            public void poll() throws LuaError
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if( m_hardAbortMessage != null ) LuaThread.yield( state, NONE );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        m_globals = new LuaTable();
 | 
				
			||||||
 | 
					        state.setupThread( m_globals );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Add basic libraries
 | 
				
			||||||
 | 
					        m_globals.load( state, new BaseLib() );
 | 
				
			||||||
 | 
					        m_globals.load( state, new TableLib() );
 | 
				
			||||||
 | 
					        m_globals.load( state, new StringLib() );
 | 
				
			||||||
 | 
					        m_globals.load( state, new MathLib() );
 | 
				
			||||||
 | 
					        m_globals.load( state, new CoroutineLib() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Remove globals we don't want to expose
 | 
					        // Remove globals we don't want to expose
 | 
				
			||||||
        m_globals.set( "collectgarbage", LuaValue.NIL );
 | 
					        m_globals.rawset( "collectgarbage", Constants.NIL );
 | 
				
			||||||
        m_globals.set( "dofile", LuaValue.NIL );
 | 
					        m_globals.rawset( "dofile", Constants.NIL );
 | 
				
			||||||
        m_globals.set( "loadfile", LuaValue.NIL );
 | 
					        m_globals.rawset( "loadfile", Constants.NIL );
 | 
				
			||||||
        m_globals.set( "module", LuaValue.NIL );
 | 
					        m_globals.rawset( "print", Constants.NIL );
 | 
				
			||||||
        m_globals.set( "require", LuaValue.NIL );
 | 
					 | 
				
			||||||
        m_globals.set( "package", LuaValue.NIL );        
 | 
					 | 
				
			||||||
        m_globals.set( "io", LuaValue.NIL );
 | 
					 | 
				
			||||||
        m_globals.set( "os", LuaValue.NIL );
 | 
					 | 
				
			||||||
        m_globals.set( "print", LuaValue.NIL );
 | 
					 | 
				
			||||||
        m_globals.set( "luajava", LuaValue.NIL );
 | 
					 | 
				
			||||||
        m_globals.set( "debug", LuaValue.NIL );
 | 
					 | 
				
			||||||
        m_globals.set( "newproxy", LuaValue.NIL );
 | 
					 | 
				
			||||||
        m_globals.set( "__inext", LuaValue.NIL );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Add version globals
 | 
					        // Add version globals
 | 
				
			||||||
        m_globals.set( "_VERSION", "Lua 5.1" );
 | 
					        m_globals.rawset( "_VERSION", valueOf( "Lua 5.1" ) );
 | 
				
			||||||
        m_globals.set( "_HOST", computer.getAPIEnvironment().getComputerEnvironment().getHostString() );
 | 
					        m_globals.rawset( "_HOST", valueOf( computer.getAPIEnvironment().getComputerEnvironment().getHostString() ) );
 | 
				
			||||||
        m_globals.set( "_CC_DEFAULT_SETTINGS", toValue( ComputerCraft.default_computer_settings ) );
 | 
					        m_globals.rawset( "_CC_DEFAULT_SETTINGS", valueOf( ComputerCraft.default_computer_settings ) );
 | 
				
			||||||
        if( ComputerCraft.disable_lua51_features )
 | 
					        if( ComputerCraft.disable_lua51_features )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            m_globals.set( "_CC_DISABLE_LUA51_FEATURES", toValue( true ) );
 | 
					            m_globals.rawset( "_CC_DISABLE_LUA51_FEATURES", Constants.TRUE );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Our main function will go here
 | 
					        // Our main function will go here
 | 
				
			||||||
@@ -132,7 +129,7 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
        String[] names = api.getNames();
 | 
					        String[] names = api.getNames();
 | 
				
			||||||
        for( String name : names )
 | 
					        for( String name : names )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            m_globals.set( name, table );
 | 
					            m_globals.rawset( name, table );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -147,48 +144,23 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        try
 | 
					        try
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Read the whole bios into a string
 | 
					            LuaFunction value = LoadState.load( m_state, bios, "@bios.lua", m_globals );
 | 
				
			||||||
            String biosText;
 | 
					            m_mainRoutine = new LuaThread( m_state, value, m_globals );
 | 
				
			||||||
            try
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                InputStreamReader isr;
 | 
					 | 
				
			||||||
                try
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    isr = new InputStreamReader( bios, "UTF-8" );
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                catch( UnsupportedEncodingException e )
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    isr = new InputStreamReader( bios );
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                BufferedReader reader = new BufferedReader( isr );
 | 
					 | 
				
			||||||
                StringBuilder fileText = new StringBuilder( "" );
 | 
					 | 
				
			||||||
                String line = reader.readLine();
 | 
					 | 
				
			||||||
                while( line != null ) {
 | 
					 | 
				
			||||||
                    fileText.append( line );
 | 
					 | 
				
			||||||
                    line = reader.readLine();
 | 
					 | 
				
			||||||
                    if( line != null ) {
 | 
					 | 
				
			||||||
                        fileText.append( "\n" );
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                biosText = fileText.toString();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            catch( IOException e )
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                throw new LuaError( "Could not read file" );
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            // Load it
 | 
					 | 
				
			||||||
            LuaValue program = m_assert.call( m_loadString.call( 
 | 
					 | 
				
			||||||
                toValue( biosText ), toValue( "bios.lua" )
 | 
					 | 
				
			||||||
            ));
 | 
					 | 
				
			||||||
            m_mainRoutine = m_coroutine_create.call( program );
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        catch( LuaError e )
 | 
					        catch( CompileException e )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if( m_mainRoutine != null )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                m_mainRoutine.abandon();
 | 
				
			||||||
 | 
					                m_mainRoutine = null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        catch( IOException e )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            ComputerCraft.log.warn( "Could not load bios.lua ", e );
 | 
					            ComputerCraft.log.warn( "Could not load bios.lua ", e );
 | 
				
			||||||
            if( m_mainRoutine != null )
 | 
					            if( m_mainRoutine != null )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                ((LuaThread)m_mainRoutine).abandon();
 | 
					                m_mainRoutine.abandon();
 | 
				
			||||||
                m_mainRoutine = null;
 | 
					                m_mainRoutine = null;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -209,32 +181,25 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        try
 | 
					        try
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LuaValue[] resumeArgs;
 | 
					            Varargs resumeArgs = Constants.NONE;
 | 
				
			||||||
            if( eventName != null )
 | 
					            if( eventName != null )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                resumeArgs = toValues( arguments, 2 );
 | 
					                resumeArgs = varargsOf( valueOf( eventName ), toValues( arguments ) );
 | 
				
			||||||
                resumeArgs[0] = m_mainRoutine;
 | 
					 | 
				
			||||||
                resumeArgs[1] = toValue( eventName );
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                resumeArgs = new LuaValue[1];
 | 
					 | 
				
			||||||
                resumeArgs[0] = m_mainRoutine;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Varargs results = m_coroutine_resume.invoke( LuaValue.varargsOf( resumeArgs ) );
 | 
					            Varargs results = m_mainRoutine.resume( resumeArgs );
 | 
				
			||||||
            if( m_hardAbortMessage != null )
 | 
					            if( m_hardAbortMessage != null )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new LuaError( m_hardAbortMessage );
 | 
					                throw new LuaError( m_hardAbortMessage );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if( results.arg1().checkboolean() == false )
 | 
					            else if( !results.first().checkBoolean() )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new LuaError( results.arg(2).checkstring().toString() );
 | 
					                throw new LuaError( results.arg( 2 ).checkString() );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                LuaValue filter = results.arg(2);
 | 
					                LuaValue filter = results.arg( 2 );
 | 
				
			||||||
                if( filter.isstring() )
 | 
					                if( filter.isString() )
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    m_eventFilter = filter.toString();
 | 
					                    m_eventFilter = filter.toString();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -244,15 +209,15 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            LuaThread mainThread = (LuaThread)m_mainRoutine;
 | 
					            LuaThread mainThread = m_mainRoutine;
 | 
				
			||||||
            if( mainThread.getStatus().equals("dead") )
 | 
					            if( mainThread.getStatus().equals( "dead" ) )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                m_mainRoutine = null;
 | 
					                m_mainRoutine = null;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        catch( LuaError e )
 | 
					        catch( LuaError e )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            ((LuaThread)m_mainRoutine).abandon();
 | 
					            m_mainRoutine.abandon();
 | 
				
			||||||
            m_mainRoutine = null;
 | 
					            m_mainRoutine = null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        finally
 | 
					        finally
 | 
				
			||||||
@@ -298,7 +263,7 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        if( m_mainRoutine != null )
 | 
					        if( m_mainRoutine != null )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LuaThread mainThread = (LuaThread)m_mainRoutine;
 | 
					            LuaThread mainThread = m_mainRoutine;
 | 
				
			||||||
            mainThread.abandon();
 | 
					            mainThread.abandon();
 | 
				
			||||||
            m_mainRoutine = null;
 | 
					            m_mainRoutine = null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -306,11 +271,6 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private void tryAbort() throws LuaError
 | 
					    private void tryAbort() throws LuaError
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
//        while( m_stopped )
 | 
					 | 
				
			||||||
//        {
 | 
					 | 
				
			||||||
//            m_coroutine_yield.call();
 | 
					 | 
				
			||||||
//        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        String abortMessage = m_softAbortMessage;
 | 
					        String abortMessage = m_softAbortMessage;
 | 
				
			||||||
        if( abortMessage != null )
 | 
					        if( abortMessage != null )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -324,29 +284,31 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        LuaTable table = new LuaTable();
 | 
					        LuaTable table = new LuaTable();
 | 
				
			||||||
        String[] methods = object.getMethodNames();
 | 
					        String[] methods = object.getMethodNames();
 | 
				
			||||||
        for(int i=0; i<methods.length; ++i )
 | 
					        for( int i = 0; i < methods.length; ++i )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if( methods[i] != null )
 | 
					            if( methods[ i ] != null )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                final int method = i;
 | 
					                final int method = i;
 | 
				
			||||||
                final ILuaObject apiObject = object;
 | 
					                final ILuaObject apiObject = object;
 | 
				
			||||||
                final String methodName = methods[i];
 | 
					                final String methodName = methods[ i ];
 | 
				
			||||||
                table.set( methodName, new VarArgFunction() {
 | 
					                table.rawset( methodName, new VarArgFunction()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    @Override
 | 
					                    @Override
 | 
				
			||||||
                    public Varargs invoke( Varargs _args )
 | 
					                    public Varargs invoke( final LuaState state, Varargs _args ) throws LuaError
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        tryAbort();
 | 
					                        tryAbort();
 | 
				
			||||||
                        Object[] arguments = toObjects( _args, 1 );
 | 
					                        Object[] arguments = toObjects( _args, 1 );
 | 
				
			||||||
                        Object[] results;
 | 
					                        Object[] results;
 | 
				
			||||||
                        try
 | 
					                        try
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            results = apiObject.callMethod( new ILuaContext() {
 | 
					                            results = apiObject.callMethod( new ILuaContext()
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
                                @Nonnull
 | 
					                                @Nonnull
 | 
				
			||||||
                                @Override
 | 
					                                @Override
 | 
				
			||||||
                                public Object[] pullEvent( String filter ) throws LuaException, InterruptedException
 | 
					                                public Object[] pullEvent( String filter ) throws LuaException, InterruptedException
 | 
				
			||||||
                                {
 | 
					                                {
 | 
				
			||||||
                                    Object[] results = pullEventRaw( filter );
 | 
					                                    Object[] results = pullEventRaw( filter );
 | 
				
			||||||
                                    if( results.length >= 1 && results[0].equals( "terminate" ) )
 | 
					                                    if( results.length >= 1 && results[ 0 ].equals( "terminate" ) )
 | 
				
			||||||
                                    {
 | 
					                                    {
 | 
				
			||||||
                                        throw new LuaException( "Terminated", 0 );
 | 
					                                        throw new LuaException( "Terminated", 0 );
 | 
				
			||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
@@ -366,14 +328,17 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
                                {
 | 
					                                {
 | 
				
			||||||
                                    try
 | 
					                                    try
 | 
				
			||||||
                                    {
 | 
					                                    {
 | 
				
			||||||
                                        LuaValue[] yieldValues = toValues( yieldArgs, 0 );
 | 
					                                        Varargs results = LuaThread.yield( state, toValues( yieldArgs ) );
 | 
				
			||||||
                                        Varargs results = m_coroutine_yield.invoke( LuaValue.varargsOf( yieldValues ) );
 | 
					 | 
				
			||||||
                                        return toObjects( results, 1 );
 | 
					                                        return toObjects( results, 1 );
 | 
				
			||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
                                    catch( OrphanedThread e )
 | 
					                                    catch( OrphanedThread e )
 | 
				
			||||||
                                    {
 | 
					                                    {
 | 
				
			||||||
                                        throw new InterruptedException();
 | 
					                                        throw new InterruptedException();
 | 
				
			||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
 | 
					                                    catch( Throwable e )
 | 
				
			||||||
 | 
					                                    {
 | 
				
			||||||
 | 
					                                        throw new RuntimeException( e );
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                @Override
 | 
					                                @Override
 | 
				
			||||||
@@ -448,10 +413,10 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
                                        Object[] response = pullEvent( "task_complete" );
 | 
					                                        Object[] response = pullEvent( "task_complete" );
 | 
				
			||||||
                                        if( response.length >= 3 && response[ 1 ] instanceof Number && response[ 2 ] instanceof Boolean )
 | 
					                                        if( response.length >= 3 && response[ 1 ] instanceof Number && response[ 2 ] instanceof Boolean )
 | 
				
			||||||
                                        {
 | 
					                                        {
 | 
				
			||||||
                                            if( ( (Number)response[ 1 ] ).intValue() == taskID )
 | 
					                                            if( ((Number) response[ 1 ]).intValue() == taskID )
 | 
				
			||||||
                                            {
 | 
					                                            {
 | 
				
			||||||
                                                Object[] returnValues = new Object[ response.length - 3 ];
 | 
					                                                Object[] returnValues = new Object[ response.length - 3 ];
 | 
				
			||||||
                                                if( (Boolean)response[ 2 ] )
 | 
					                                                if( (Boolean) response[ 2 ] )
 | 
				
			||||||
                                                {
 | 
					                                                {
 | 
				
			||||||
                                                    // Extract the return values from the event and return them
 | 
					                                                    // Extract the return values from the event and return them
 | 
				
			||||||
                                                    System.arraycopy( response, 3, returnValues, 0, returnValues.length );
 | 
					                                                    System.arraycopy( response, 3, returnValues, 0, returnValues.length );
 | 
				
			||||||
@@ -460,9 +425,9 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
                                                else
 | 
					                                                else
 | 
				
			||||||
                                                {
 | 
					                                                {
 | 
				
			||||||
                                                    // Extract the error message from the event and raise it
 | 
					                                                    // Extract the error message from the event and raise it
 | 
				
			||||||
                                                    if( response.length >= 4 && response[3] instanceof String )
 | 
					                                                    if( response.length >= 4 && response[ 3 ] instanceof String )
 | 
				
			||||||
                                                    {
 | 
					                                                    {
 | 
				
			||||||
                                                        throw new LuaException( (String)response[ 3 ] );
 | 
					                                                        throw new LuaException( (String) response[ 3 ] );
 | 
				
			||||||
                                                    }
 | 
					                                                    }
 | 
				
			||||||
                                                    else
 | 
					                                                    else
 | 
				
			||||||
                                                    {
 | 
					                                                    {
 | 
				
			||||||
@@ -492,7 +457,7 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            throw new LuaError( "Java Exception Thrown: " + t.toString(), 0 );
 | 
					                            throw new LuaError( "Java Exception Thrown: " + t.toString(), 0 );
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        return LuaValue.varargsOf( toValues( results, 0 ) );
 | 
					                        return toValues( results );
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                } );
 | 
					                } );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -500,174 +465,151 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
        return table;
 | 
					        return table;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private LuaValue toValue( Object object )
 | 
					    private LuaValue toValue( Object object, Map<Object, LuaValue> values )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if( object == null )
 | 
					        if( object == null )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return LuaValue.NIL;
 | 
					            return Constants.NIL;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if( object instanceof Number )
 | 
					        else if( object instanceof Number )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            double d = ((Number)object).doubleValue();
 | 
					            double d = ((Number) object).doubleValue();
 | 
				
			||||||
            return LuaValue.valueOf( d );
 | 
					            return valueOf( d );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if( object instanceof Boolean )
 | 
					        else if( object instanceof Boolean )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            boolean b = (Boolean) object;
 | 
					            return valueOf( (Boolean) object );
 | 
				
			||||||
            return LuaValue.valueOf( b );
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if( object instanceof String )
 | 
					        else if( object instanceof String )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            String s = object.toString();
 | 
					            String s = object.toString();
 | 
				
			||||||
            return LuaValue.valueOf( s );
 | 
					            return valueOf( s );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if( object instanceof byte[] )
 | 
					        else if( object instanceof byte[] )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            byte[] b = (byte[]) object;
 | 
					            byte[] b = (byte[]) object;
 | 
				
			||||||
            return LuaValue.valueOf( Arrays.copyOf( b, b.length ) );
 | 
					            return valueOf( Arrays.copyOf( b, b.length ) );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if( object instanceof Map )
 | 
					        else if( object instanceof Map )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Table:
 | 
					            // Table:
 | 
				
			||||||
            // Start remembering stuff
 | 
					            // Start remembering stuff
 | 
				
			||||||
            boolean clearWhenDone = false;
 | 
					            if( values == null )
 | 
				
			||||||
            try
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if( m_valuesInProgress == null )
 | 
					                values = new IdentityHashMap<>();
 | 
				
			||||||
                {
 | 
					            }
 | 
				
			||||||
                    m_valuesInProgress = new IdentityHashMap<>();
 | 
					            else if( values.containsKey( object ) )
 | 
				
			||||||
                    clearWhenDone = true;
 | 
					            {
 | 
				
			||||||
                }
 | 
					                return values.get( object );
 | 
				
			||||||
                else if( m_valuesInProgress.containsKey( object ) )
 | 
					            }
 | 
				
			||||||
                {
 | 
					            LuaTable table = new LuaTable();
 | 
				
			||||||
                    return m_valuesInProgress.get( object );
 | 
					            values.put( object, table );
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                LuaValue table = new LuaTable();
 | 
					 | 
				
			||||||
                m_valuesInProgress.put( object, table );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Convert all keys
 | 
					            // Convert all keys
 | 
				
			||||||
                for( Map.Entry<?, ?> pair : ((Map<?, ?>) object).entrySet() )
 | 
					            for( Map.Entry<?, ?> pair : ((Map<?, ?>) object).entrySet() )
 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    LuaValue key = toValue( pair.getKey() );
 | 
					 | 
				
			||||||
                    LuaValue value = toValue( pair.getValue() );
 | 
					 | 
				
			||||||
                    if( !key.isnil() && !value.isnil() )
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        table.set( key, value );
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                return table;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            finally
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Clear (if exiting top level)
 | 
					                LuaValue key = toValue( pair.getKey(), values );
 | 
				
			||||||
                if( clearWhenDone )
 | 
					                LuaValue value = toValue( pair.getValue(), values );
 | 
				
			||||||
 | 
					                if( !key.isNil() && !value.isNil() )
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    m_valuesInProgress = null;
 | 
					                    table.rawset( key, value );
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            return table;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if( object instanceof ILuaObject )
 | 
					        else if( object instanceof ILuaObject )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return wrapLuaObject( (ILuaObject)object );
 | 
					            return wrapLuaObject( (ILuaObject) object );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return LuaValue.NIL;
 | 
					            return Constants.NIL;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private LuaValue[] toValues( Object[] objects, int leaveEmpty )
 | 
					    private Varargs toValues( Object[] objects )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if( objects == null || objects.length == 0 )
 | 
					        if( objects == null || objects.length == 0 )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return new LuaValue[ leaveEmpty ];
 | 
					            return Constants.NONE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        LuaValue[] values = new LuaValue[objects.length + leaveEmpty];
 | 
					        LuaValue[] values = new LuaValue[ objects.length ];
 | 
				
			||||||
        for( int i=0; i<values.length; ++i )
 | 
					        for( int i = 0; i < values.length; ++i )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if( i < leaveEmpty )
 | 
					            Object object = objects[ i ];
 | 
				
			||||||
            {
 | 
					            values[ i ] = toValue( object, null );
 | 
				
			||||||
                values[i] = null;
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Object object = objects[i - leaveEmpty];
 | 
					 | 
				
			||||||
            values[i] = toValue( object );
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return values;
 | 
					        return varargsOf( values );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Object toObject( LuaValue value )
 | 
					    private static Object toObject( LuaValue value, Map<LuaValue, Object> objects )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        switch( value.type() )
 | 
					        switch( value.type() )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            case LuaValue.TNIL:
 | 
					            case Constants.TNIL:
 | 
				
			||||||
            case LuaValue.TNONE: 
 | 
					            case Constants.TNONE:
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return null;
 | 
					                return null;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            case LuaValue.TINT:
 | 
					            case Constants.TINT:
 | 
				
			||||||
            case LuaValue.TNUMBER:
 | 
					            case Constants.TNUMBER:
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return value.todouble();
 | 
					                return value.toDouble();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            case LuaValue.TBOOLEAN:
 | 
					            case Constants.TBOOLEAN:
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return value.toboolean();
 | 
					                return value.toBoolean();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            case LuaValue.TSTRING:
 | 
					            case Constants.TSTRING:
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                LuaString str = value.checkstring();
 | 
					                return value.toString();
 | 
				
			||||||
                return str.tojstring();
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            case LuaValue.TTABLE:
 | 
					            case Constants.TTABLE:
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Table:
 | 
					                // Table:
 | 
				
			||||||
                boolean clearWhenDone = false;
 | 
					                // Start remembering stuff
 | 
				
			||||||
                try
 | 
					                if( objects == null )
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    // Start remembering stuff
 | 
					                    objects = new IdentityHashMap<>();
 | 
				
			||||||
                    if( m_objectsInProgress == null )
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        m_objectsInProgress = new IdentityHashMap<>();
 | 
					 | 
				
			||||||
                        clearWhenDone = true;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    else if( m_objectsInProgress.containsKey( value ) )
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        return m_objectsInProgress.get( value );
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    Map<Object, Object> table = new HashMap<>();
 | 
					 | 
				
			||||||
                    m_objectsInProgress.put( value, table );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // Convert all keys
 | 
					 | 
				
			||||||
                    LuaValue k = LuaValue.NIL;
 | 
					 | 
				
			||||||
                    while( true )
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        Varargs keyValue = value.next( k );
 | 
					 | 
				
			||||||
                        k = keyValue.arg1();
 | 
					 | 
				
			||||||
                        if( k.isnil() )
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            break;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        LuaValue v = keyValue.arg(2);
 | 
					 | 
				
			||||||
                        Object keyObject = toObject(k);
 | 
					 | 
				
			||||||
                        Object valueObject = toObject(v);
 | 
					 | 
				
			||||||
                        if( keyObject != null && valueObject != null )
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            table.put( keyObject, valueObject );
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    return table;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                finally
 | 
					                else if( objects.containsKey( value ) )
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    // Clear (if exiting top level)
 | 
					                    return objects.get( value );
 | 
				
			||||||
                    if( clearWhenDone )
 | 
					                }
 | 
				
			||||||
 | 
					                Map<Object, Object> table = new HashMap<>();
 | 
				
			||||||
 | 
					                objects.put( value, table );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                LuaTable luaTable = (LuaTable) value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Convert all keys
 | 
				
			||||||
 | 
					                LuaValue k = Constants.NIL;
 | 
				
			||||||
 | 
					                while( true )
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Varargs keyValue;
 | 
				
			||||||
 | 
					                    try
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        m_objectsInProgress = null;
 | 
					                        keyValue = luaTable.next( k );
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    catch( LuaError luaError )
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    k = keyValue.first();
 | 
				
			||||||
 | 
					                    if( k.isNil() )
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    LuaValue v = keyValue.arg( 2 );
 | 
				
			||||||
 | 
					                    Object keyObject = toObject( k, objects );
 | 
				
			||||||
 | 
					                    Object valueObject = toObject( v, objects );
 | 
				
			||||||
 | 
					                    if( keyObject != null && valueObject != null )
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        table.put( keyObject, valueObject );
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                return table;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -676,15 +618,15 @@ public class LuaJLuaMachine implements ILuaMachine
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Object[] toObjects( Varargs values, int startIdx )
 | 
					    private static Object[] toObjects( Varargs values, int startIdx )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        int count = values.narg();
 | 
					        int count = values.count();
 | 
				
			||||||
        Object[] objects = new Object[ count - startIdx + 1 ];
 | 
					        Object[] objects = new Object[ count - startIdx + 1 ];
 | 
				
			||||||
        for( int n=startIdx; n<=count; ++n )
 | 
					        for( int n = startIdx; n <= count; ++n )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            int i = n - startIdx;
 | 
					            int i = n - startIdx;
 | 
				
			||||||
            LuaValue value = values.arg(n);
 | 
					            LuaValue value = values.arg( n );
 | 
				
			||||||
            objects[i] = toObject( value );
 | 
					            objects[ i ] = toObject( value, null );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return objects;
 | 
					        return objects;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
		Reference in New Issue
	
	Block a user