1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-25 22:53:22 +00:00

Merge pull request #298 from SquidDev-CC/ComputerCraft/feature/luaj-bit32

Replace BitAPI with a LuaJ implementation of bit32
This commit is contained in:
SquidDev 2017-11-14 21:32:19 +00:00
commit 060fb21bdb
6 changed files with 195 additions and 110 deletions

Binary file not shown.

View File

@ -0,0 +1,181 @@
/*******************************************************************************
* Copyright (c) 2012 Luaj.org. 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.vm2.lib;
import org.luaj.vm2.LuaInteger;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
/**
* Subclass of LibFunction that implements the Lua standard {@code bit32} library.
*/
public class Bit32Lib extends ZeroArgFunction
{
public LuaValue call( )
{
LuaTable t = new LuaTable();
bind( t, Bit32LibV.class, new String[] {
"band", "bnot", "bor", "btest", "bxor", "extract", "replace"
} );
bind( t, Bit32Lib2.class, new String[] {
"arshift", "lrotate", "lshift", "rrotate", "rshift"
} );
env.set( "bit32", t );
return t;
}
public static final class Bit32LibV extends VarArgFunction
{
public Varargs invoke( Varargs args )
{
switch( opcode )
{
case 0: // band
{
int result = -1;
for( int i = 1; i <= args.narg(); i++ )
{
result &= args.checkint( i );
}
return bitsToValue( result );
}
case 1: // bnot
return bitsToValue( ~args.checkint( 1 ) );
case 2: // bot
{
int result = 0;
for( int i = 1; i <= args.narg(); i++ )
{
result |= args.checkint( i );
}
return bitsToValue( result );
}
case 3: // btest
{
int bits = -1;
for( int i = 1; i <= args.narg(); i++ )
{
bits &= args.checkint( i );
}
return valueOf( bits != 0 );
}
case 4: // bxor
{
int result = 0;
for( int i = 1; i <= args.narg(); i++ )
{
result ^= args.checkint( i );
}
return bitsToValue( result );
}
case 5: // extract
{
int field = args.checkint( 2 );
int width = args.optint( 3, 1 );
if( field < 0 ) argerror( 2, "field cannot be negative" );
if( width <= 0 ) argerror( 3, "width must be postive" );
if( field + width > 32 ) error( "trying to access non-existent bits" );
return bitsToValue( (args.checkint( 1 ) >>> field) & (-1 >>> (32 - width)) );
}
case 6: // replace
{
int n = args.checkint( 1 );
int v = args.checkint( 2 );
int field = args.checkint( 3 );
int width = args.optint( 4, 1 );
if( field < 0 ) argerror( 3, "field cannot be negative" );
if( width <= 0 ) argerror( 4, "width must be postive" );
if( field + width > 32 ) error( "trying to access non-existent bits" );
int mask = (-1 >>> (32 - width)) << field;
n = (n & ~mask) | ((v << field) & mask);
return bitsToValue( n );
}
}
return NIL;
}
}
public static final class Bit32Lib2 extends TwoArgFunction
{
public LuaValue call( LuaValue arg1, LuaValue arg2 )
{
switch( opcode )
{
case 0: // arshift
{
int x = arg1.checkint();
int disp = arg2.checkint();
return disp >= 0 ? bitsToValue( x >> disp ) : bitsToValue( x << -disp );
}
case 1: // lrotate
return rotate( arg1.checkint(), arg2.checkint() );
case 2: // lshift
return shift( arg1.checkint(), arg2.checkint() );
case 3: // rrotate
return rotate( arg1.checkint(), -arg2.checkint() );
case 4: // rshift
return shift( arg1.checkint(), -arg2.checkint() );
}
return NIL;
}
}
static LuaValue rotate( int x, int disp )
{
if( disp < 0 )
{
disp = -disp & 31;
return bitsToValue( (x >>> disp) | (x << (32 - disp)) );
}
else
{
disp = disp & 31;
return bitsToValue( (x << disp) | (x >>> (32 - disp)) );
}
}
static LuaValue shift( int x, int disp )
{
if( disp >= 32 || disp <= -32 )
{
return ZERO;
}
else if( disp >= 0 )
{
return bitsToValue( x << disp );
}
else
{
return bitsToValue( x >>> -disp );
}
}
private static LuaValue bitsToValue( int x )
{
return x < 0 ? LuaValue.valueOf( (long) x & 0xFFFFFFFFL ) : LuaInteger.valueOf( x );
}
}

View File

@ -1,95 +0,0 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2017. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.core.apis;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import javax.annotation.Nonnull;
import static dan200.computercraft.core.apis.ArgumentHelper.getInt;
// Contributed by Nia
// Based on LuaBit (http://luaforge.net/projects/bit)
public class BitAPI implements ILuaAPI
{
private static final int BNOT = 0;
private static final int BAND = 1;
private static final int BOR = 2;
private static final int BXOR = 3;
private static final int BRSHIFT = 4;
private static final int BLSHIFT = 5;
private static final int BLOGIC_RSHIFT = 6;
public BitAPI( IAPIEnvironment _environment )
{
}
@Override
public String[] getNames()
{
return new String[] {
"bit"
};
}
@Override
public void startup( )
{
}
@Override
public void advance( double _dt )
{
}
@Override
public void shutdown( )
{
}
@Nonnull
@Override
public String[] getMethodNames() {
return new String[] {
"bnot", "band", "bor", "bxor",
"brshift", "blshift", "blogic_rshift"
};
}
@Override
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException
{
int ret = 0;
switch(method) {
case BNOT:
ret = ~getInt( args, 0 );
break;
case BAND:
ret = getInt( args, 0 ) & getInt( args, 1 );
break;
case BOR:
ret = getInt( args, 0 ) | getInt( args, 1 );
break;
case BXOR:
ret = getInt( args, 0 ) ^ getInt( args, 1 );
break;
case BRSHIFT:
ret = getInt( args, 0 ) >> getInt( args, 1 );
break;
case BLSHIFT:
ret = getInt( args, 0 ) << getInt( args, 1 );
break;
case BLOGIC_RSHIFT:
ret = getInt( args, 0 ) >>> getInt( args, 1 );
break;
}
return new Object[]{ ret&0xFFFFFFFFL };
}
}

View File

@ -611,7 +611,6 @@ private void createAPIs()
m_apis.add( new FSAPI( m_apiEnvironment ) );
m_apis.add( new PeripheralAPI( m_apiEnvironment ) );
m_apis.add( new OSAPI( m_apiEnvironment ) );
m_apis.add( new BitAPI( m_apiEnvironment ) );
//m_apis.add( new BufferAPI( m_apiEnvironment ) );
if( ComputerCraft.http_enable )
{

View File

@ -17,6 +17,7 @@
import dan200.computercraft.core.computer.MainThread;
import org.luaj.vm2.*;
import org.luaj.vm2.lib.Bit32Lib;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;
@ -54,6 +55,7 @@ public LuaJLuaMachine( Computer computer )
// Create an environment to run in
m_globals = JsePlatform.debugGlobals();
m_globals.load( new Bit32Lib() );
m_loadString = m_globals.get("loadstring");
m_assert = m_globals.get("assert");

View File

@ -55,18 +55,6 @@ if _VERSION == "Lua 5.1" then
table.unpack = unpack
table.pack = function( ... ) return { n = select( "#", ... ), ... } end
-- Install the bit32 api
local nativebit = bit
bit32 = {}
bit32.arshift = nativebit.brshift
bit32.band = nativebit.band
bit32.bnot = nativebit.bnot
bit32.bor = nativebit.bor
bit32.btest = function( a, b ) return nativebit.band(a,b) ~= 0 end
bit32.bxor = nativebit.bxor
bit32.lshift = nativebit.blshift
bit32.rshift = nativebit.blogic_rshift
if _CC_DISABLE_LUA51_FEATURES then
-- Remove the Lua 5.1 features that will be removed when we update to Lua 5.2, for compatibility testing.
-- See "disable_lua51_functions" in ComputerCraft.cfg
@ -76,11 +64,21 @@ if _VERSION == "Lua 5.1" then
unpack = nil
math.log10 = nil
table.maxn = nil
bit = nil
else
-- Inject a stub for the old bit library
_G.bit = {
bnot = bit32.bnot,
band = bit32.band,
bor = bit32.bor,
bxor = bit32.bxor,
brshift = bit32.arshift,
blshift = bit32.lshift,
blogic_rshift = bit32.rshift
}
end
end
if _VERSION == "Lua 5.3" then
if _VERSION == "Lua 5.3" and not bit32 then
-- If we're on Lua 5.3, install the bit32 api from Lua 5.2
-- (Loaded from a string so this file will still parse on <5.3 lua)
load( [[