All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.luaj.vm2.lib.Bit32Lib Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
* 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.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;

/**
 * Subclass of LibFunction that implements the Lua standard {@code bit32} library.
 * 

* Typically, this library is included as part of a call to either * {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()} *

 {@code
 * Globals globals = JsePlatform.standardGlobals();
 * System.out.println( globals.get("bit32").get("bnot").call( LuaValue.valueOf(2) ) );
 * } 
*

* To instantiate and use it directly, * link it into your globals table via {@link LuaValue#load(LuaValue)} using code such as: *

 {@code
 * Globals globals = new Globals();
 * globals.load(new JseBaseLib());
 * globals.load(new PackageLib());
 * globals.load(new Bit32Lib());
 * System.out.println( globals.get("bit32").get("bnot").call( LuaValue.valueOf(2) ) );
 * } 
*

* This has been implemented to match as closely as possible the behavior in the corresponding library in C. * @see LibFunction * @see org.luaj.vm2.lib.jse.JsePlatform * @see org.luaj.vm2.lib.jme.JmePlatform * @see Lua 5.2 Bitwise Operation Lib Reference */ public class Bit32Lib extends TwoArgFunction { public Bit32Lib() { } /** Perform one-time initialization on the library by creating a table * containing the library functions, adding that table to the supplied environment, * adding the table to package.loaded, and returning table as the return value. * @param modname the module name supplied if this is loaded via 'require'. * @param env the environment to load into, which must be a Globals instance. */ public LuaValue call(LuaValue modname, LuaValue env) { 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); env.get("package").get("loaded").set("bit32", t); return t; } static final class Bit32LibV extends VarArgFunction { public Varargs invoke(Varargs args) { switch ( opcode ) { case 0: return Bit32Lib.band( args ); case 1: return Bit32Lib.bnot( args ); case 2: return Bit32Lib.bor( args ); case 3: return Bit32Lib.btest( args ); case 4: return Bit32Lib.bxor( args ); case 5: return Bit32Lib.extract( args.checkint(1), args.checkint(2), args.optint(3, 1) ); case 6: return Bit32Lib.replace( args.checkint(1), args.checkint(2), args.checkint(3), args.optint(4, 1) ); } return NIL; } } static final class Bit32Lib2 extends TwoArgFunction { public LuaValue call(LuaValue arg1, LuaValue arg2) { switch ( opcode ) { case 0: return Bit32Lib.arshift(arg1.checkint(), arg2.checkint()); case 1: return Bit32Lib.lrotate(arg1.checkint(), arg2.checkint()); case 2: return Bit32Lib.lshift(arg1.checkint(), arg2.checkint()); case 3: return Bit32Lib.rrotate(arg1.checkint(), arg2.checkint()); case 4: return Bit32Lib.rshift(arg1.checkint(), arg2.checkint()); } return NIL; } } static LuaValue arshift(int x, int disp) { if (disp >= 0) { return bitsToValue(x >> disp); } else { return bitsToValue(x << -disp); } } static LuaValue rshift(int x, int disp) { if (disp >= 32 || disp <= -32) { return ZERO; } else if (disp >= 0) { return bitsToValue(x >>> disp); } else { return bitsToValue(x << -disp); } } static LuaValue lshift(int x, int disp) { if (disp >= 32 || disp <= -32) { return ZERO; } else if (disp >= 0) { return bitsToValue(x << disp); } else { return bitsToValue(x >>> -disp); } } static Varargs band( Varargs args ) { int result = -1; for ( int i = 1; i <= args.narg(); i++ ) { result &= args.checkint(i); } return bitsToValue( result ); } static Varargs bnot( Varargs args ) { return bitsToValue( ~args.checkint(1) ); } static Varargs bor( Varargs args ) { int result = 0; for ( int i = 1; i <= args.narg(); i++ ) { result |= args.checkint(i); } return bitsToValue( result ); } static Varargs btest( Varargs args ) { int bits = -1; for ( int i = 1; i <= args.narg(); i++ ) { bits &= args.checkint(i); } return valueOf( bits != 0 ); } static Varargs bxor( Varargs args ) { int result = 0; for ( int i = 1; i <= args.narg(); i++ ) { result ^= args.checkint(i); } return bitsToValue( result ); } static LuaValue lrotate(int x, int disp) { if (disp < 0) { return rrotate(x, -disp); } else { disp = disp & 31; return bitsToValue((x << disp) | (x >>> (32 - disp))); } } static LuaValue rrotate(int x, int disp) { if (disp < 0) { return lrotate(x, -disp); } else { disp = disp & 31; return bitsToValue((x >>> disp) | (x << (32 - disp))); } } static LuaValue extract(int n, int field, int width) { 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((n >>> field) & (-1 >>> (32 - width))); } static LuaValue replace(int n, int v, int field, int width) { 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); } private static LuaValue bitsToValue( int x ) { return ( x < 0 ) ? valueOf((double) ((long) x & 0xFFFFFFFFL)) : valueOf(x); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy