Skip to content

Commit

Permalink
Prefix all loaded strings with "="
Browse files Browse the repository at this point in the history
Whilst this is not consistent with normal Lua, this is required in order
to remain compatible with LuaJ.
  • Loading branch information
SquidDev committed May 7, 2017
1 parent 40b27c5 commit 72dab14
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 1 deletion.
92 changes: 92 additions & 0 deletions src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.squiddev.cobalt.debug.DebugFrame;
import org.squiddev.cobalt.debug.DebugHandler;
import org.squiddev.cobalt.debug.DebugState;
import org.squiddev.cobalt.function.LibFunction;
import org.squiddev.cobalt.function.LuaFunction;
import org.squiddev.cobalt.function.VarArgFunction;
import org.squiddev.cobalt.lib.*;
Expand Down Expand Up @@ -120,6 +121,9 @@ private void handleSoftAbort() throws LuaError {
m_globals.load( state, new MathLib() );
m_globals.load( state, new CoroutineLib() );

// Register custom load/loadstring provider which automatically adds prefixes.
LibFunction.bind( state, m_globals, PrefixLoader.class, new String[]{ "load", "loadstring" } );

// Remove globals we don't want to expose
m_globals.rawset( "collectgarbage", Constants.NIL );
m_globals.rawset( "dofile", Constants.NIL );
Expand Down Expand Up @@ -625,4 +629,92 @@ private static Object[] toObjects( Varargs values, int startIdx )
}
return objects;
}

private static class PrefixLoader extends VarArgFunction
{
private static final LuaString FUNCTION_STR = valueOf( "function" );
private static final LuaString EQ_STR = valueOf( "=" );

@Override
public Varargs invoke( LuaState state, Varargs args ) throws LuaError
{
switch (opcode)
{
case 0: // "load", // ( func [,chunkname] ) -> chunk | nil, msg
{
LuaValue func = args.arg( 1 ).checkFunction();
LuaString chunkname = args.arg( 2 ).optLuaString( FUNCTION_STR );
if( !chunkname.startsWith( '@' ) && !chunkname.startsWith( '=' ) )
{
chunkname = OperationHelper.concat( EQ_STR, chunkname );
}
return BaseLib.loadStream( state, new StringInputStream( state, func ), chunkname );
}
case 1: // "loadstring", // ( string [,chunkname] ) -> chunk | nil, msg
{
LuaString script = args.arg( 1 ).checkLuaString();
LuaString chunkname = args.arg( 2 ).optLuaString( script );
if( !chunkname.startsWith( '@' ) && !chunkname.startsWith( '=' ) )
{
chunkname = OperationHelper.concat( EQ_STR, chunkname );
}
return BaseLib.loadStream( state, script.toInputStream(), chunkname );
}
}

return NONE;
}
}

private static class StringInputStream extends InputStream
{
private final LuaState state;
private final LuaValue func;
private byte[] bytes;
private int offset, remaining = 0;

public StringInputStream( LuaState state, LuaValue func )
{
this.state = state;
this.func = func;
}

@Override
public int read() throws IOException
{
if( remaining <= 0 )
{
LuaValue s;
try
{
s = OperationHelper.call( state, func );
} catch (LuaError e)
{
throw new IOException( e );
}

if( s.isNil() )
{
return -1;
}
LuaString ls;
try
{
ls = s.strvalue();
} catch (LuaError e)
{
throw new IOException( e );
}
bytes = ls.bytes;
offset = ls.offset;
remaining = ls.length;
if( remaining <= 0 )
{
return -1;
}
}
--remaining;
return bytes[offset++];
}
}
}
2 changes: 1 addition & 1 deletion src/main/resources/assets/computercraft/lua/bios.lua
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ end
loadfile = function( _sFile, _tEnv )
local file = fs.open( _sFile, "r" )
if file then
local func, err = load( file.readAll(), fs.getName( _sFile ), "t", _tEnv )
local func, err = load( file.readAll(), "@" .. fs.getName( _sFile ), "t", _tEnv )
file.close()
return func, err
end
Expand Down

0 comments on commit 72dab14

Please sign in to comment.