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

org.luaj.vm2.LoadState Maven / Gradle / Ivy

There is a newer version: 3.0.1
Show newest version
/*******************************************************************************
* Copyright (c) 2009 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;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.luaj.vm2.compiler.DumpState;


/**
* Class to undump compiled lua bytecode into a {@link Prototype} instances.
* 

* The {@link LoadState} class implements {@link Globals#Undumper} * which is used to undump a string of bytes that represent a lua binary file * using either the C-based lua compiler, or luaj's {@link DumpState#dump} function. *

* The canonical method to load and execute code is done * indirectly using the Globals: *

 {@code
* Globals globals = JsePlatform.standardGlobals();
* LuaValue chunk = globasl.load("print('hello, world')", "main.lua");
* chunk.call();
* } 
* This should work regardless of which {@link Globals.Compiler} * has been installed. *

* By default, when using {@link JsePlatform} or {@JmePlatform} * to construct globals, the {@link LoadState} is installed * as the default {@link Globals#undumper}. *

* * A lua binary file is created via {@link DumpState#dump}: *

 {@code
* Globals globals = JsePlatform.standardGlobals();
* Prototype p = globals.compilePrototype(new StringReader("print('hello, world')"), "main.lua");
* ByteArrayOutputStream o = new ByteArrayOutputStream();
* DumpState.dump(p, o, false);
* byte[] lua_binary_file_bytes = o.toByteArray();
* } 
* * The {@link LoadState} may be used directly to undump these bytes: *
 {@code
* Prototypep = LoadState.instance.undump(new ByteArrayInputStream(lua_binary_file_bytes), "main.lua");
* LuaClosure c = new LuaClosure(p, globals);
* c.call();
* } 
* * * More commonly, the {@link Globals#undumper} may be used to undump them: *
 {@code
* Prototype p = globals.loadPrototype(new ByteArrayInputStream(lua_binary_file_bytes), "main.lua", "b");
* LuaClosure c = new LuaClosure(p, globals);
* c.call();
* } 
* * @see LuaCompiler * @see LuaClosure * @see LuaFunction * @see LoadState#compiler * @see LoadState#load(InputStream, String, LuaValue) * @see LuaC * @see LuaJC */ public class LoadState implements Globals.Undumper { /** Shared instance of Globals.Undumper to use loading prototypes from binary lua files */ public static final Globals.Undumper instance = new LoadState(); /** format corresponding to non-number-patched lua, all numbers are floats or doubles */ public static final int NUMBER_FORMAT_FLOATS_OR_DOUBLES = 0; /** format corresponding to non-number-patched lua, all numbers are ints */ public static final int NUMBER_FORMAT_INTS_ONLY = 1; /** format corresponding to number-patched lua, all numbers are 32-bit (4 byte) ints */ public static final int NUMBER_FORMAT_NUM_PATCH_INT32 = 4; // type constants public static final int LUA_TINT = (-2); public static final int LUA_TNONE = (-1); public static final int LUA_TNIL = 0; public static final int LUA_TBOOLEAN = 1; public static final int LUA_TLIGHTUSERDATA = 2; public static final int LUA_TNUMBER = 3; public static final int LUA_TSTRING = 4; public static final int LUA_TTABLE = 5; public static final int LUA_TFUNCTION = 6; public static final int LUA_TUSERDATA = 7; public static final int LUA_TTHREAD = 8; public static final int LUA_TVALUE = 9; /** The character encoding to use for file encoding. Null means the default encoding */ public static String encoding = null; /** Signature byte indicating the file is a compiled binary chunk */ public static final byte[] LUA_SIGNATURE = { '\033', 'L', 'u', 'a' }; /** Data to catch conversion errors */ public static final byte[] LUAC_TAIL = { (byte) 0x19, (byte) 0x93, '\r', '\n', (byte) 0x1a, '\n', }; /** Name for compiled chunks */ public static final String SOURCE_BINARY_STRING = "binary string"; /** for header of binary files -- this is Lua 5.2 */ public static final int LUAC_VERSION = 0x52; /** for header of binary files -- this is the official format */ public static final int LUAC_FORMAT = 0; /** size of header of binary files */ public static final int LUAC_HEADERSIZE = 12; // values read from the header private int luacVersion; private int luacFormat; private boolean luacLittleEndian; private int luacSizeofInt; private int luacSizeofSizeT; private int luacSizeofInstruction; private int luacSizeofLuaNumber; private int luacNumberFormat; /** input stream from which we are loading */ public final DataInputStream is; /** Name of what is being loaded? */ String name; private static final LuaValue[] NOVALUES = {}; private static final Prototype[] NOPROTOS = {}; private static final LocVars[] NOLOCVARS = {}; private static final LuaString[] NOSTRVALUES = {}; private static final Upvaldesc[] NOUPVALDESCS = {}; private static final int[] NOINTS = {}; /** Read buffer */ private byte[] buf = new byte[512]; /** Install this class as the standard Globals.Undumper for the supplied Globals */ public static void install(Globals globals) { globals.undumper = instance; } /** Load a 4-byte int value from the input stream * @return the int value laoded. **/ int loadInt() throws IOException { is.readFully(buf,0,4); return luacLittleEndian? (buf[3] << 24) | ((0xff & buf[2]) << 16) | ((0xff & buf[1]) << 8) | (0xff & buf[0]): (buf[0] << 24) | ((0xff & buf[1]) << 16) | ((0xff & buf[2]) << 8) | (0xff & buf[3]); } /** Load an array of int values from the input stream * @return the array of int values laoded. **/ int[] loadIntArray() throws IOException { int n = loadInt(); if ( n == 0 ) return NOINTS; // read all data at once int m = n << 2; if ( buf.length < m ) buf = new byte[m]; is.readFully(buf,0,m); int[] array = new int[n]; for ( int i=0, j=0; i> 52) & 0x7ffL) - 1023; if ( e >= 0 && e < 31 ) { long f = bits & 0xFFFFFFFFFFFFFL; int shift = 52 - e; long intPrecMask = ( 1L << shift ) - 1; if ( ( f & intPrecMask ) == 0 ) { int intValue = (int)( f >> shift ) | ( 1 << e ); return LuaInteger.valueOf( ( ( bits >> 63 ) != 0 ) ? -intValue : intValue ); } } return LuaValue.valueOf( Double.longBitsToDouble(bits) ); } /** * Load a number from a binary chunk * @return the {@link LuaValue} loaded * @throws IOException if an i/o exception occurs */ LuaValue loadNumber() throws IOException { if ( luacNumberFormat == NUMBER_FORMAT_INTS_ONLY ) { return LuaInteger.valueOf( loadInt() ); } else { return longBitsToLuaNumber( loadInt64() ); } } /** * Load a list of constants from a binary chunk * @param f the function prototype * @throws IOException if an i/o exception occurs */ void loadConstants(Prototype f) throws IOException { int n = loadInt(); LuaValue[] values = n>0? new LuaValue[n]: NOVALUES; for ( int i=0; i0? new Prototype[n]: NOPROTOS; for ( int i=0; i0? new Upvaldesc[n]: NOUPVALDESCS; for (int i=0; i0? new LocVars[n]: NOLOCVARS; for ( int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy