Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * $Id: LuaState.java 157 2012-10-05 23:00:17Z [email protected] $
- * See LICENSE.txt for license terms.
- */
- package li.cil.repack.com.naef.jnlua;
- import java.io.ByteArrayInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.lang.ref.PhantomReference;
- import java.lang.ref.ReferenceQueue;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import java.util.HashSet;
- import java.util.Set;
- import li.cil.repack.com.naef.jnlua.JavaReflector.Metamethod;
- /**
- * JNLua core class representing a Lua instance.
- *
- * <p>
- * The class performs extensive checking on all arguments and its state.
- * Specifically, the following exceptions are thrown under the indicated
- * conditions:
- * </p>
- *
- * <table class="doc">
- * <tr>
- * <th>Exception</th>
- * <th>When</th>
- * </tr>
- * <tr>
- * <td>{@link java.lang.NullPointerException}</td>
- * <td>if an argument is <code>null</code> and the API does not explicitly
- * specify that the argument may be <code>null</code></td>
- * </tr>
- * <tr>
- * <td>{@link java.lang.IllegalStateException}</td>
- * <td>if the Lua state is closed and the API does not explicitly specify that
- * the method may be invoked on a closed Lua state</td>
- * </tr>
- * <tr>
- * <td>{@link java.lang.IllegalArgumentException}</td>
- * <td>if a stack index refers to a non-valid stack location and the API does
- * not explicitly specify that the stack index may be non-valid</td>
- * </tr>
- * <tr>
- * <td>{@link java.lang.IllegalArgumentException}</td>
- * <td>if a stack index refers to an stack location with value type that is
- * different from the value type explicitly specified in the API</td>
- * </tr>
- * <tr>
- * <td>{@link java.lang.IllegalArgumentException}</td>
- * <td>if a count is negative or out of range and the API does not explicitly
- * specify that the count may be negative or out of range</td>
- * </tr>
- * <tr>
- * <td>{@link li.cil.repack.com.naef.jnlua.LuaRuntimeException}</td>
- * <td>if a Lua runtime error occurs</td>
- * </tr>
- * <tr>
- * <td>{@link li.cil.repack.com.naef.jnlua.LuaSyntaxException}</td>
- * <td>if the syntax of a Lua chunk is incorrect</td>
- * </tr>
- * <tr>
- * <td>{@link li.cil.repack.com.naef.jnlua.LuaMemoryAllocationException}</td>
- * <td>if the Lua memory allocator runs out of memory or if a JNI allocation
- * fails</td>
- * </tr>
- * <tr>
- * <td>{@link li.cil.repack.com.naef.jnlua.LuaGcMetamethodException}</td>
- * <td>if an error occurs running a <code>__gc</code> metamethod during garbage
- * collection</td>
- * </tr>
- * <tr>
- * <td>{@link li.cil.repack.com.naef.jnlua.LuaMessageHandlerException}</td>
- * <td>if an error occurs running the message handler of a protected call</td>
- * </tr>
- * </table>
- */
- public class LuaState {
- // -- Static
- /**
- * Multiple returns pseudo return value count.
- */
- public static final int MULTRET = -1;
- /**
- * Registry pseudo-index.
- */
- public static final int REGISTRYINDEX;
- /**
- * OK status.
- *
- * @since JNLua 1.0.0
- */
- public static final int OK = 0;
- /**
- * Status indicating that a thread is suspended.
- */
- public static final int YIELD = 1;
- /**
- * Registry index of the main thread.
- *
- * @since JNLua 1.0.0
- */
- public static final int RIDX_MAINTHREAD = 1;
- /**
- * Registry index of the global environment.
- *
- * @since JNLua 1.0.0
- */
- public static final int RIDX_GLOBALS = 2;
- /**
- * The JNLua version. The format is <major>.<minor>.
- */
- public static final String VERSION = "1.1";
- /**
- * The Lua version. The format is <major>.<minor>.
- */
- public static final String LUA_VERSION;
- static {
- NativeSupport.getInstance().getLoader().load();
- REGISTRYINDEX = lua_registryindex();
- LUA_VERSION = lua_version();
- }
- protected int REGISTRYINDEX() {
- return REGISTRYINDEX;
- }
- protected String LUA_VERSION() {
- return LUA_VERSION;
- }
- /**
- * The API version.
- */
- private static final int APIVERSION = 3;
- // -- State
- /**
- * Whether the <code>lua_State</code> on the JNI side is owned by the Java
- * state and must be closed when the Java state closes.
- */
- private boolean ownState;
- /**
- * The <code>lua_State</code> pointer on the JNI side. <code>0</code>
- * implies that this Lua state is closed. The field is modified exclusively
- * on the JNI side and must not be touched on the Java side.
- */
- private long luaState;
- /**
- * The <code>lua_State</code> pointer on the JNI side for the running
- * coroutine. This field is modified exclusively on the JNI side and must
- * not be touched on the Java side.
- */
- private long luaThread;
- /**
- * The yield flag. This field is modified from both the JNI side and Java
- * side and signals a pending yield.
- */
- private boolean yield;
- /**
- * The maximum amount of memory the may be used by the Lua state, in bytes.
- * This can be adjusted to limit the amount of memory a state may use. If
- * it is reduced while a VM is active this can very quickly lead to out of
- * memory errors.
- */
- private int luaMemoryTotal;
- /**
- * The amount of memory currently used by the Lua state, in bytes. This is
- * set from the JNI side and must not be modified from the Java side.
- */
- private int luaMemoryUsed;
- /**
- * Ensures proper finalization of this Lua state.
- */
- private Object finalizeGuardian;
- /**
- * The class loader for dynamically loading classes.
- */
- private ClassLoader classLoader;
- /**
- * Reflects Java objects.
- */
- private JavaReflector javaReflector;
- /**
- * Converts between Lua types and Java types.
- */
- private Converter converter;
- /**
- * Set of Lua proxy phantom references for pre-mortem cleanup.
- */
- private Set<LuaValueProxyRef> proxySet = new HashSet<LuaValueProxyRef>();
- /**
- * Reference queue for pre-mortem cleanup.
- */
- private ReferenceQueue<LuaValueProxyImpl> proxyQueue = new ReferenceQueue<LuaValueProxyImpl>();
- // -- Construction
- /**
- * Creates a new instance. The class loader of this Lua state is set to the
- * context class loader of the calling thread. The Java reflector and the
- * converter are initialized with the default implementations. The Lua
- * state may allocate as much memory as it wants.
- *
- * @see #getClassLoader()
- * @see #setClassLoader(ClassLoader)
- * @see #getJavaReflector()
- * @see #setJavaReflector(JavaReflector)
- * @see #getConverter()
- * @see #setConverter(Converter)
- */
- public LuaState() {
- this(0L, 0);
- }
- /**
- * Creates a new instance. The class loader of this Lua state is set to the
- * context class loader of the calling thread. The Java reflector and the
- * converter are initialized with the default implementations. The Lua
- * state may allocate only as much memory as specified. This is enforced
- * by a custom allocator that is only used if a maximum memory is given.
- *
- * @param memory
- * the maximum amount of memory this Lua state may use, in bytes
- * @see #getClassLoader()
- * @see #setClassLoader(ClassLoader)
- * @see #getJavaReflector()
- * @see #setJavaReflector(JavaReflector)
- * @see #getConverter()
- * @see #setConverter(Converter)
- */
- public LuaState(int memory) {
- this(0L, validateMemory(memory));
- }
- /**
- * Creates a new instance.
- */
- private LuaState(long luaState, int memory) {
- ownState = luaState == 0L;
- luaMemoryTotal = memory;
- lua_newstate(APIVERSION, luaState);
- check();
- // Create a finalize guardian
- finalizeGuardian = new Object() {
- @Override
- public void finalize() {
- synchronized (LuaState.this) {
- closeInternal();
- }
- }
- };
- // Add metamethods
- for (int i = 0; i < JavaReflector.Metamethod.values().length; i++) {
- final JavaReflector.Metamethod metamethod = JavaReflector.Metamethod
- .values()[i];
- lua_pushjavafunction(new JavaFunction() {
- @Override
- public int invoke(LuaState luaState) {
- JavaFunction javaFunction = getMetamethod(
- luaState.toJavaObjectRaw(1), metamethod);
- if (javaFunction != null) {
- return javaFunction.invoke(LuaState.this);
- } else {
- throw new UnsupportedOperationException(
- metamethod.getMetamethodName());
- }
- }
- });
- lua_setfield(-2, metamethod.getMetamethodName());
- }
- lua_pop(1);
- // Set fields
- classLoader = Thread.currentThread().getContextClassLoader();
- javaReflector = DefaultJavaReflector.getInstance();
- converter = DefaultConverter.getInstance();
- }
- // -- Properties
- /**
- * Returns the class loader of this Lua state. The class loader is used for
- * dynamically loading classes.
- *
- * <p>
- * The method may be invoked on a closed Lua state.
- * </p>
- *
- * @return the class loader
- */
- public synchronized ClassLoader getClassLoader() {
- return classLoader;
- }
- /**
- * Sets the class loader of this Lua state. The class loader is used for
- * dynamically loading classes.
- *
- * <p>
- * The method may be invoked on a closed Lua state.
- * </p>
- *
- * @param classLoader
- * the class loader to set
- */
- public synchronized void setClassLoader(ClassLoader classLoader) {
- if (classLoader == null) {
- throw new NullPointerException();
- }
- this.classLoader = classLoader;
- }
- /**
- * Returns the Java reflector of this Lua state.
- *
- * <p>
- * The method may be invoked on a closed Lua state.
- * </p>
- *
- * @return the Java reflector converter
- */
- public synchronized JavaReflector getJavaReflector() {
- return javaReflector;
- }
- /**
- * Sets the Java reflector of this Lua state.
- *
- * <p>
- * The method may be invoked on a closed Lua state.
- * </p>
- *
- * @param javaReflector
- * the Java reflector
- */
- public synchronized void setJavaReflector(JavaReflector javaReflector) {
- if (javaReflector == null) {
- throw new NullPointerException();
- }
- this.javaReflector = javaReflector;
- }
- /**
- * Returns a metamethod for a specified object. If the object implements the
- * {@link li.cil.repack.com.naef.jnlua.JavaReflector} interface, the metamethod is first
- * queried from the object. If the object provides the requested metamethod,
- * that metamethod is returned. Otherwise, the method returns the metamethod
- * provided by the Java reflector configured in this Lua state.
- *
- * <p>
- * Clients requiring access to metamethods should go by this method to
- * ensure consistent class-by-class overriding of the Java reflector.
- * </p>
- *
- * @param obj
- * the object, or <code>null</code>
- * @return the Java reflector
- */
- public synchronized JavaFunction getMetamethod(Object obj,
- Metamethod metamethod) {
- if (obj != null && obj instanceof JavaReflector) {
- JavaFunction javaFunction = ((JavaReflector) obj)
- .getMetamethod(metamethod);
- if (javaFunction != null) {
- return javaFunction;
- }
- }
- return javaReflector.getMetamethod(metamethod);
- }
- /**
- * Returns the converter of this Lua state.
- *
- * <p>
- * The method may be invoked on a closed Lua state.
- * </p>
- *
- * @return the converter
- */
- public synchronized Converter getConverter() {
- return converter;
- }
- /**
- * Sets the converter of this Lua state.
- *
- * <p>
- * The method may be invoked on a closed Lua state.
- * </p>
- *
- * @param converter
- * the converter
- */
- public synchronized void setConverter(Converter converter) {
- if (converter == null) {
- throw new NullPointerException();
- }
- this.converter = converter;
- }
- // -- Memory
- /**
- * Returns the maximum memory consumption of this Lua state. This is the
- * maximum raw memory Lua may allocate for this state, in bytes.
- *
- * @return the maximum memory consumption
- */
- public synchronized int getTotalMemory() {
- return luaMemoryTotal;
- }
- /**
- * Sets the maximum amount of memory this Lua state may allocate. This is
- * the size of the raw memory the Lua library may allocate for this tate,
- * in bytes. Note that you can only set the maximum memory consumption for
- * states that were created to enforce a maximum memory consumption.
- *
- * @param value
- * the new maximum memory size this state may allocate
- */
- public synchronized void setTotalMemory(int value) {
- if (luaMemoryTotal < 1) {
- throw new IllegalStateException("cannot set maximum memory for this state");
- }
- luaMemoryTotal = validateMemory(value);
- }
- /**
- * Returns the current amount of unused memory by this Lua state. This is
- * the size of the total available memory minus the raw memory currently
- * allocated by this state, in bytes.
- *
- * This is guaranteed to be less or equal to {@link #getTotalMemory()} and
- * larger or equal to zero.
- *
- * This only returns something not zero if a maximum memory consumption is
- * enforced by this state. Otherwise it will always return zero.
- *
- * @return the current memory consumption
- */
- public synchronized int getFreeMemory() {
- // This is the reason we use free amount instead of used amount: if we
- // lower the max memory we can get below used memory, which would be
- // weird; so we just say free memory is zero, which is more intuitive
- // and true at the same time.
- return Math.max(0, luaMemoryTotal - luaMemoryUsed);
- }
- /**
- * Returns the approximate memory usage of the Lua coroutine on the
- * Lua stack
- *
- * @return the approximate coroutine memory usage
- */
- public synchronized int getCoroutineMemory() {
- return lua_getcoroutinemem();
- }
- // -- Life cycle
- /**
- * Returns whether this Lua state is open.
- *
- * <p>
- * The method may be invoked on a closed Lua state.
- * </p>
- *
- * @return whether this Lua state is open
- */
- public final synchronized boolean isOpen() {
- return isOpenInternal();
- }
- /**
- * Closes this Lua state and releases all resources.
- *
- * <p>
- * The method may be invoked on a closed Lua state and has no effect in that
- * case.
- * </p>
- */
- public synchronized void close() {
- closeInternal();
- }
- /**
- * Performs a garbage collection operation. Please see the Lua Reference
- * Manual for an explanation of the actions, arguments and return values.
- *
- * @param what
- * the operation to perform
- * @param data
- * the argument required by some operations
- * @return a return value depending on the GC operation performed
- */
- public synchronized int gc(GcAction what, int data) {
- check();
- return lua_gc(what.ordinal(), data);
- }
- // -- Registration
- /**
- * Opens the specified library in this Lua state. The library is pushed onto
- * the stack.
- *
- * @param library
- * the library
- */
- public synchronized void openLib(Library library) {
- check();
- library.open(this);
- }
- /**
- * Opens the Lua standard libraries and the JNLua Java module in this Lua
- * state.
- *
- * <p>
- * The method opens all libraries defined by the {@link Library}
- * enumeration.
- * </p>
- */
- public synchronized void openLibs() {
- check();
- for (Library library : Library.values()) {
- library.open(this);
- pop(1);
- }
- }
- /**
- * Registers a named Java function as a global variable.
- *
- * @param namedJavaFunction
- * the Java function to register
- */
- public synchronized void register(NamedJavaFunction namedJavaFunction) {
- check();
- String name = namedJavaFunction.getName();
- if (name == null) {
- throw new IllegalArgumentException("anonymous function");
- }
- pushJavaFunction(namedJavaFunction);
- setGlobal(name);
- }
- /**
- * Registers a module and pushes the module on the stack. Optionally, a
- * module can be registered globally. As of Lua 5.2, modules are <i>not</i>
- * expected to set global variables anymore.
- *
- * @param moduleName
- * the module name
- * @param namedJavaFunctions
- * the Java functions of the module
- * @param global
- * whether to register the module globally
- */
- public synchronized void register(String moduleName,
- NamedJavaFunction[] namedJavaFunctions, boolean global) {
- check();
- /*
- * The following code corresponds to luaL_requiref() and must be kept in
- * sync. The original code cannot be called due to the necessity of
- * pushing each C function with an individual closure.
- */
- newTable(0, namedJavaFunctions.length);
- for (int i = 0; i < namedJavaFunctions.length; i++) {
- String name = namedJavaFunctions[i].getName();
- if (name == null) {
- throw new IllegalArgumentException(String.format(
- "anonymous function at index %d", i));
- }
- pushJavaFunction(namedJavaFunctions[i]);
- setField(-2, name);
- }
- lua_getsubtable(REGISTRYINDEX(), "_LOADED");
- pushValue(-2);
- setField(-2, moduleName);
- pop(1);
- if (global) {
- rawGet(REGISTRYINDEX(), RIDX_GLOBALS);
- pushValue(-2);
- setField(-2, moduleName);
- pop(1);
- }
- }
- // -- Load and dump
- /**
- * Loads a Lua chunk from an input stream and pushes it on the stack as a
- * function. Depending on the value of mode, the the Lua chunk can either be
- * a pre-compiled binary chunk or a UTF-8 encoded text chunk.
- *
- * @param inputStream
- * the input stream
- * @param chunkName
- * the name of the chunk for use in error messages
- * @param mode
- * <code>"b"</code> to accept binary, <code>"t"</code> to accept
- * text, or <code>"bt"</code> to accept both
- * @throws IOException
- * if an IO error occurs
- */
- public synchronized void load(InputStream inputStream, String chunkName,
- String mode) throws IOException {
- check();
- lua_load(inputStream, chunkName, mode);
- }
- /**
- * Loads a Lua chunk from a string and pushes it on the stack as a function.
- * The string must contain a source chunk.
- *
- * @param chunk
- * the Lua source chunk
- * @param chunkName
- * the name of the chunk for use in error messages
- */
- public synchronized void load(String chunk, String chunkName) {
- check();
- try {
- load(new ByteArrayInputStream(chunk.getBytes("UTF-8")), chunkName,
- "t");
- } catch (IOException e) {
- throw new LuaMemoryAllocationException(e.getMessage(), e);
- }
- }
- /**
- * Dumps the function on top of the stack as a pre-compiled binary chunk
- * into an output stream.
- *
- * @param outputStream
- * the output stream
- * @throws IOException
- * if an IO error occurs
- */
- public synchronized void dump(OutputStream outputStream) throws IOException {
- check();
- lua_dump(outputStream);
- }
- // -- Call
- /**
- * Calls a Lua function. The function to call and the specified number of
- * arguments are on the stack. After the call, the specified number of
- * returns values are on stack. If the number of return values has been
- * specified as {@link #MULTRET}, the number of values on the stack
- * corresponds the to number of values actually returned by the called
- * function.
- *
- * @param argCount
- * the number of arguments
- * @param returnCount
- * the number of return values, or {@link #MULTRET} to accept all
- * values returned by the function
- */
- public synchronized void call(int argCount, int returnCount) {
- check();
- lua_pcall(argCount, returnCount);
- }
- // -- Globals
- /**
- * Pushes the value of a global variable on the stack.
- *
- * @param name
- * the global variable name
- */
- public synchronized void getGlobal(String name) {
- check();
- lua_getglobal(name);
- }
- /**
- * Sets the value on top of the stack as a global variable and pops the
- * value from the stack.
- *
- * @param name
- * the global variable name
- */
- public synchronized void setGlobal(String name)
- throws LuaMemoryAllocationException, LuaRuntimeException {
- check();
- lua_setglobal(name);
- }
- // -- Stack push
- /**
- * Pushes a boolean value on the stack.
- *
- * @param b
- * the boolean value to push
- */
- public synchronized void pushBoolean(boolean b) {
- check();
- lua_pushboolean(b ? 1 : 0);
- }
- /**
- * Pushes a byte array value as a string value on the stack.
- *
- * @param b
- * the byte array to push
- */
- public synchronized void pushByteArray(byte[] b) {
- check();
- lua_pushbytearray(b);
- }
- /**
- * Pushes an integer value as a number value on the stack.
- *
- * @param n
- * the integer value to push
- */
- public synchronized void pushInteger(int n) {
- check();
- lua_pushinteger(n);
- }
- /**
- * Pushes a Java function on the stack.
- *
- * @param javaFunction
- * the function to push
- */
- public synchronized void pushJavaFunction(JavaFunction javaFunction) {
- check();
- lua_pushjavafunction(javaFunction);
- }
- /**
- * Pushes a Java object on the stack with conversion. The object is
- * processed the by the configured converter.
- *
- * @param object
- * the Java object
- * @see #getConverter()
- * @see #setConverter(Converter)
- */
- public synchronized void pushJavaObject(Object object) {
- check();
- getConverter().convertJavaObject(this, object);
- }
- /**
- * Pushes a Java object on the stack. The object is pushed "as is", i.e.
- * without conversion.
- *
- * <p>
- * If you require to push a Lua value that represents the Java object, then
- * invoke <code>pushJavaObject(object)</code>.
- * </p>
- *
- * <p>
- * You cannot push <code>null</code> without conversion since
- * <code>null</code> is not a Java object. The converter converts
- * <code>null</code> to <code>nil</code>.
- * </p>
- *
- * @param object
- * the Java object
- * @see #pushJavaObject(Object)
- */
- public synchronized void pushJavaObjectRaw(Object object) {
- check();
- lua_pushjavaobject(object);
- }
- /**
- * Pushes a nil value on the stack.
- */
- public synchronized void pushNil() {
- check();
- lua_pushnil();
- }
- /**
- * Pushes a number value on the stack.
- *
- * @param n
- * the number to push
- */
- public synchronized void pushNumber(double n) {
- check();
- lua_pushnumber(n);
- }
- /**
- * Pushes a string value on the stack.
- *
- * @param s
- * the string value to push
- */
- public synchronized void pushString(String s) {
- check();
- lua_pushstring(s);
- }
- // -- Stack type test
- /**
- * Returns whether the value at the specified stack index is a boolean.
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the value is a boolean
- */
- public synchronized boolean isBoolean(int index) {
- check();
- return lua_isboolean(index) != 0;
- }
- /**
- * Returns whether the value at the specified stack index is a C function.
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the value is a function
- */
- public synchronized boolean isCFunction(int index) {
- check();
- return lua_iscfunction(index) != 0;
- }
- /**
- * Returns whether the value at the specified stack index is a function
- * (either a C function, a Java function or a Lua function.)
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the value is a function
- */
- public synchronized boolean isFunction(int index) {
- check();
- return lua_isfunction(index) != 0;
- }
- /**
- * Returns whether the value at the specified stack index is a Java
- * function.
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the value is a function
- */
- public synchronized boolean isJavaFunction(int index) {
- check();
- return lua_isjavafunction(index) != 0;
- }
- /**
- * Returns whether the value at the specified stack index is convertible to
- * a Java object of the specified type. The conversion is checked by the
- * configured converter.
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the value is convertible to a Java object of the
- * specified type
- * @see #setConverter(Converter)
- * @see #getConverter()
- */
- public synchronized boolean isJavaObject(int index, Class<?> type) {
- check();
- return converter.getTypeDistance(this, index, type) != Integer.MAX_VALUE;
- }
- /**
- * Returns whether the value at the specified stack index is a Java object.
- *
- * <p>
- * Note that the method does not perform conversion. If you want to check if
- * a value <i>is convertible to</i> a Java object, then invoke <code>
- * isJavaObject(index, Object.class)</code>.
- * </p>
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the value is a Java object
- * @see #isJavaObject(int, Class)
- */
- public synchronized boolean isJavaObjectRaw(int index) {
- check();
- return lua_isjavaobject(index) != 0;
- }
- /**
- * Returns whether the value at the specified stack index is
- * <code>nil</code>.
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the value is <code>nil</code>
- */
- public synchronized boolean isNil(int index) {
- check();
- return lua_isnil(index) != 0;
- }
- /**
- * Returns whether the specified stack index is non-valid.
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the stack index is non-valid
- */
- public synchronized boolean isNone(int index) {
- check();
- return lua_isnone(index) != 0;
- }
- /**
- * Returns whether the specified stack index is non-valid or its value is
- * <code>nil</code>.
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the stack index is non-valid or its value is
- * <code>nil</code>
- */
- public synchronized boolean isNoneOrNil(int index) {
- check();
- return lua_isnoneornil(index) != 0;
- }
- /**
- * Returns whether the value at the specified stack index is a number or a
- * string convertible to a number.
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the value is a number or a string convertible to a number
- */
- public synchronized boolean isNumber(int index) {
- check();
- return lua_isnumber(index) != 0;
- }
- /**
- * Returns whether the value at the specified stack index is a string or a
- * number (which is always convertible to a string.)
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the value is a string or a number
- */
- public synchronized boolean isString(int index) {
- check();
- return lua_isstring(index) != 0;
- }
- /**
- * Returns whether the value at the specified stack index is a table.
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the value is a table
- */
- public synchronized boolean isTable(int index) {
- check();
- return lua_istable(index) != 0;
- }
- /**
- * Returns whether the value at the specified stack index is a thread.
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return whether the value is a thread
- */
- public synchronized boolean isThread(int index) {
- check();
- return lua_isthread(index) != 0;
- }
- // -- Stack query
- /**
- * Compares the values at two specified stack indexes for the specified
- * operator according to Lua semantics.
- *
- * <p>
- * Any stack index may be non-valid in which case the method returns
- * <code>false</code>.
- * </p>
- *
- * @param index1
- * the first stack index
- * @param index2
- * the second stack index
- * @param operator
- * the operator
- * @return the result of the comparison
- * @since JNLua 1.0.0
- */
- public synchronized boolean compare(int index1, int index2,
- RelOperator operator) {
- check();
- return lua_compare(index1, index2, operator.ordinal()) != 0;
- }
- /**
- * Returns whether the values at two specified stack indexes are equal
- * according to Lua semantics.
- *
- * @param index1
- * the first stack index
- * @param index2
- * the second stack index
- * @return whether the values are equal
- * @deprecated instead use {@link #compare(int, int, RelOperator)}
- */
- public synchronized boolean equal(int index1, int index2) {
- return compare(index1, index2, RelOperator.EQ);
- }
- /**
- * Returns the length of the value at the specified stack index. Please see
- * the Lua Reference Manual for the definition of the raw length of a value.
- *
- * @param index
- * the stack index
- * @return the length
- * @deprecated instead use {@link #rawLen(int)}
- */
- public synchronized int length(int index) {
- return rawLen(index);
- }
- /**
- * Returns whether a value at a first stack index is less than the value at
- * a second stack index according to Lua semantics.
- *
- * @param index1
- * the first stack index
- * @param index2
- * the second stack index
- * @return whether the value at the first index is less than the value at
- * the second index
- * @deprecated instead use {@link #compare(int, int, RelOperator)}
- */
- public synchronized boolean lessThan(int index1, int index2)
- throws LuaMemoryAllocationException, LuaRuntimeException {
- return compare(index1, index2, RelOperator.LT);
- }
- /**
- * Bypassing metatable logic, returns whether the values at two specified
- * stack indexes are equal according to Lua semantics.
- *
- * <p>
- * Any stack index may be non-valid in which case the method returns
- * <code>false</code>.
- * </p>
- *
- * @param index1
- * the first stack index
- * @param index2
- * the second stack index
- * @return whether the values are equal
- */
- public synchronized boolean rawEqual(int index1, int index2) {
- check();
- return lua_rawequal(index1, index2) != 0;
- }
- /**
- * Bypassing metatable logic, returns the length of the value at the
- * specified stack index. Please see the Lua Reference Manual for the
- * definition of the raw length of a value.
- *
- * @param index
- * the stack index
- * @return the length
- * @since JNLua 1.0.0
- */
- public synchronized int rawLen(int index) {
- check();
- return lua_rawlen(index);
- }
- /**
- * Returns the boolean representation of the value at the specified stack
- * index. The boolean representation is <code>true</code> for all values
- * except <code>false</code> and <code>nil</code>. The method also returns
- * <code>false</code> if the index is non-valid.
- *
- * @param index
- * the stack index
- * @return the boolean representation of the value
- */
- public synchronized boolean toBoolean(int index) {
- check();
- return lua_toboolean(index) != 0;
- }
- /**
- * Returns the byte array representation of the value at the specified stack
- * index. The value must be a string or a number. If the value is a number,
- * it is in place converted to a string. Otherwise, the method returns
- * <code>null</code>.
- *
- * @param index
- * the stack index
- * @return the byte array representation of the value
- */
- public synchronized byte[] toByteArray(int index) {
- check();
- return lua_tobytearray(index);
- }
- /**
- * Returns the integer representation of the value at the specified stack
- * index. The value must be a number or a string convertible to a number.
- * Otherwise, the method returns <code>0</code>.
- *
- * @param index
- * the stack index
- * @return the integer representation, or <code>0</code>
- */
- public synchronized int toInteger(int index) {
- check();
- return lua_tointeger(index);
- }
- /**
- * Returns the integer representation of the value at the specified stack
- * index. The value must be a number or a string convertible to a number.
- * Otherwise, the method returns <code>null</code>.
- *
- * @param index
- * the stack index
- * @return the integer representation, or <code>null</code>
- * @since JNLua 1.0.2
- */
- public synchronized Integer toIntegerX(int index) {
- check();
- return lua_tointegerx(index);
- }
- /**
- * Returns the Java function of the value at the specified stack index. If
- * the value is not a Java function, the method returns <code>null</code>.
- *
- * @param index
- * the stack index
- * @return the Java function, or <code>null</code>
- */
- public synchronized JavaFunction toJavaFunction(int index) {
- check();
- return lua_tojavafunction(index);
- }
- /**
- * Returns a Java object of the specified type representing the value at the
- * specified stack index. The value must be convertible to a Java object of
- * the specified type. The conversion is executed by the configured
- * converter.
- *
- * @param index
- * the stack index
- * @param type
- * the Java type to convert to
- * @return the object
- * @throws ClassCastException
- * if the conversion is not supported by the converter
- * @see #getConverter()
- * @see #setConverter(Converter)
- */
- public synchronized <T> T toJavaObject(int index, Class<T> type) {
- check();
- return converter.convertLuaValue(this, index, type);
- }
- /**
- * Returns the Java object of the value at the specified stack index. If the
- * value is not a Java object, the method returns <code>null</code>.
- *
- * <p>
- * Note that the method does not convert values to Java objects. If you
- * require <i>any</i> Java object that represents the value at the specified
- * index, then invoke <code>toJavaObject(index, Object.class)</code>.
- * </p>
- *
- * @param index
- * the stack index
- * @return the Java object, or <code>null</code>
- * @see #toJavaObject(int, Class)
- */
- public synchronized Object toJavaObjectRaw(int index) {
- check();
- return lua_tojavaobject(index);
- }
- /**
- * Returns the number representation of the value at the specified stack
- * index. The value must be a number or a string convertible to a number.
- * Otherwise, the method returns <code>0.0</code>.
- *
- * @param index
- * the stack index
- * @return the number representation, or <code>0.0</code>
- */
- public synchronized double toNumber(int index) {
- check();
- return lua_tonumber(index);
- }
- /**
- * Returns the number representation of the value at the specified stack
- * index. The value must be a number or a string convertible to a number.
- * Otherwise, the method returns <code>null</code>.
- *
- * @param index
- * the stack index
- * @return the number representation, or <code>null</code>
- * @since JNLua 1.0.2
- */
- public synchronized Double toNumberX(int index) {
- check();
- return lua_tonumberx(index);
- }
- /**
- * Returns the pointer representation of the value at the specified stack
- * index. The value must be a table, thread, function or userdata (such as a
- * Java object.) Otherwise, the method returns <code>0L</code>. Different
- * values return different pointers. Other than that, the returned value has
- * no portable significance.
- *
- * @param index
- * the stack index
- * @return the pointer representation, or <code>0L</code> if none
- */
- public synchronized long toPointer(int index) {
- check();
- return lua_topointer(index);
- }
- /**
- * Returns the string representation of the value at the specified stack
- * index. The value must be a string or a number. If the value is a number,
- * it is in place converted to a string. Otherwise, the method returns
- * <code>null</code>.
- *
- * @param index
- * the stack index
- * @return the string representation, or <code>null</code>
- */
- public synchronized String toString(int index) {
- check();
- return lua_tostring(index);
- }
- /**
- * Returns the type of the value at the specified stack index.
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return the type, or <code>null</code> if the stack index is non-valid
- */
- public synchronized LuaType type(int index) {
- check();
- int type = lua_type(index);
- return type >= 0 ? LuaType.values()[type] : null;
- }
- /**
- * Returns the name of the type at the specified stack index. The type name
- * is the display text for the Lua type except for Java objects where the
- * type name is the canonical class name.
- *
- * <p>
- * The stack index may be non-valid in which case the method returns the
- * string <code>"none"</code>.
- * </p>
- *
- * @param index
- * the index
- * @return the type name
- * @see LuaType#displayText()
- * @see Class#getCanonicalName()
- */
- public synchronized String typeName(int index) {
- check();
- LuaType type = type(index);
- if (type == null) {
- return "none";
- }
- switch (type) {
- case USERDATA:
- if (isJavaObjectRaw(index)) {
- Object object = toJavaObjectRaw(index);
- Class<?> clazz;
- if (object instanceof Class<?>) {
- clazz = (Class<?>) object;
- } else {
- clazz = object.getClass();
- }
- return clazz.getCanonicalName();
- }
- break;
- }
- return type.displayText();
- }
- // -- Stack operation
- /**
- * Returns the absolute stack index of the specified index.
- *
- * <p>
- * The stack index may be non-valid.
- * </p>
- *
- * @param index
- * the stack index
- * @return the absolute stack index
- * @since JNLua 1.0.0
- */
- public synchronized int absIndex(int index) {
- check();
- return lua_absindex(index);
- }
- /**
- * Performs an arithmetic operation with values on top of the stack using
- * Lua semantics.
- *
- * @param operator
- * the operator to apply
- * @since JNLua 1.0.0
- */
- public synchronized void arith(ArithOperator operator) {
- check();
- lua_arith(operator.ordinal());
- }
- /**
- * Concatenates the specified number values on top of the stack and replaces
- * them with the concatenated value.
- *
- * @param n
- * the number of values to concatenate
- */
- public synchronized void concat(int n) {
- check();
- lua_concat(n);
- }
- /**
- * Copies a value at a specified index to another index, replacing the value
- * at that index.
- *
- * @param fromIndex
- * the index to copy from
- * @param toIndex
- * the index to copy to
- * @since JNLua 1.0.0
- */
- public synchronized void copy(int fromIndex, int toIndex) {
- check();
- lua_copy(fromIndex, toIndex);
- }
- /**
- * Returns the number of values on the stack.
- *
- * @return the number of values on the tack
- */
- public synchronized int getTop() {
- check();
- return lua_gettop();
- }
- /**
- * Pushes the length of the value at the specified stack index on the stack.
- * The value pushed by the method corresponds to the Lua <code>#</code>
- * operator.
- *
- * @param index
- * the index for which to push the length
- * @since JNLua 1.0.0
- */
- public synchronized void len(int index) {
- check();
- lua_len(index);
- }
- /**
- * Pops the value on top of the stack inserting it at the specified index
- * and moving up elements above that index.
- *
- * @param index
- * the stack index
- */
- public synchronized void insert(int index) {
- check();
- lua_insert(index);
- }
- /**
- * Pops values from the stack.
- *
- * @param count
- * the number of values to pop
- */
- public synchronized void pop(int count) {
- check();
- lua_pop(count);
- }
- /**
- * Pushes the value at the specified index on top of the stack.
- *
- * @param index
- * the stack index
- */
- public synchronized void pushValue(int index) {
- check();
- lua_pushvalue(index);
- }
- /**
- * Removes the value at the specified stack index moving down elements above
- * that index.
- *
- * @param index
- * the stack index
- */
- public synchronized void remove(int index) {
- check();
- lua_remove(index);
- }
- /**
- * Replaces the value at the specified index with the value popped from the
- * top of the stack.
- *
- * @param index
- * the stack index
- */
- public synchronized void replace(int index) {
- check();
- lua_replace(index);
- }
- /**
- * Sets the specified index as the new top of the stack.
- *
- * <p>
- * The new top of the stack may be above the current top of the stack. In
- * this case, new values are set to <code>nil</code>.
- * </p>
- *
- * @param index
- * the index of the new top of the stack
- */
- public synchronized void setTop(int index) {
- check();
- lua_settop(index);
- }
- // -- Table
- /**
- * Pushes on the stack the value indexed by the key on top of the stack in
- * the table at the specified index. The key is replaced by the value from
- * the table.
- *
- * @param index
- * the stack index containing the table
- */
- public synchronized void getTable(int index) {
- check();
- lua_gettable(index);
- }
- /**
- * Pushes on the stack the value indexed by the specified string key in the
- * table at the specified index.
- *
- * @param index
- * the stack index containing the table
- * @param key
- * the string key
- */
- public synchronized void getField(int index, String key) {
- check();
- lua_getfield(index, key);
- }
- /**
- * Creates a new table and pushes it on the stack.
- */
- public synchronized void newTable() {
- check();
- lua_newtable();
- }
- /**
- * Creates a new table with pre-allocated space for a number of array
- * elements and record elements and pushes it on the stack.
- *
- * @param arrayCount
- * the number of array elements
- * @param recordCount
- * the number of record elements
- */
- public synchronized void newTable(int arrayCount, int recordCount) {
- check();
- lua_createtable(arrayCount, recordCount);
- }
- /**
- * Pops a key from the stack and pushes on the stack the next key and its
- * value in the table at the specified index. If there is no next key, the
- * key is popped but nothing is pushed. The method returns whether there is
- * a next key.
- *
- * @param index
- * the stack index containing the table
- * @return whether there is a next key
- */
- public synchronized boolean next(int index) {
- check();
- return lua_next(index) != 0;
- }
- /**
- * Bypassing metatable logic, pushes on the stack the value indexed by the
- * key on top of the stack in the table at the specified index. The key is
- * replaced by the value from the table.
- *
- * @param index
- * the stack index containing the table
- */
- public synchronized void rawGet(int index) {
- check();
- lua_rawget(index);
- }
- /**
- * Bypassing metatable logic, pushes on the stack the value indexed by the
- * specified integer key in the table at the specified index.
- *
- * @param index
- * the stack index containing the table
- * @param key
- * the integer key
- */
- public synchronized void rawGet(int index, int key) {
- check();
- lua_rawgeti(index, key);
- }
- /**
- * Bypassing metatable logic, sets the value on top of the stack in the
- * table at the specified index using the value on the second highest stack
- * position as the key. Both the value and the key are popped from the
- * stack.
- *
- * @param index
- * the stack index containing the table
- */
- public synchronized void rawSet(int index) {
- check();
- lua_rawset(index);
- }
- /**
- * Bypassing metatable logic, sets the value on top of the stack in the
- * table at the specified index using the specified integer key. The value
- * is popped from the stack.
- *
- * @param index
- * the stack index containing the table
- * @param key
- * the integer key
- */
- public synchronized void rawSet(int index, int key) {
- check();
- lua_rawseti(index, key);
- }
- /**
- * Sets the value on top of the stack in the table at the specified index
- * using the value on the second highest stack position as the key. Both the
- * value and the key are popped from the stack.
- *
- * @param index
- * the stack index containing the table
- */
- public synchronized void setTable(int index) {
- check();
- lua_settable(index);
- }
- /**
- * Sets the value on top of the stack in the table at the specified index
- * using the specified string key. The value is popped from the stack.
- *
- * @param index
- * the stack index containing the table
- * @param key
- * the string key
- */
- public synchronized void setField(int index, String key) {
- check();
- lua_setfield(index, key);
- }
- // -- Metatable
- /**
- * Pushes on the stack the value of the named field in the metatable of the
- * value at the specified index and returns <code>true</code>. If the value
- * does not have a metatable or if the metatable does not contain the named
- * field, nothing is pushed and the method returns <code>false</code>.
- *
- * @param index
- * the stack index containing the value to get the metafield from
- * @param key
- * the string key
- * @return whether the metafield was pushed on the stack
- */
- public synchronized boolean getMetafield(int index, String key) {
- check();
- return lua_getmetafield(index, key) != 0;
- }
- /**
- * Pushes on the stack the metatable of the value at the specified index. If
- * the value does not have a metatable, the method returns
- * <code>false</code> and nothing is pushed.
- *
- * @param index
- * the stack index containing the value to get the metatable from
- * @return whether the metatable was pushed on the stack
- */
- public synchronized boolean getMetatable(int index) {
- check();
- return lua_getmetatable(index) != 0;
- }
- /**
- * Sets the value on top of the stack as the metatable of the value at the
- * specified index. The metatable to be set is popped from the stack
- * regardless whether it can be set or not.
- *
- * @param index
- * the stack index containing the value to set the metatable for
- */
- public synchronized void setMetatable(int index) {
- check();
- lua_setmetatable(index);
- }
- // -- Thread
- /**
- * Pops the start function of a new Lua thread from the stack and creates
- * the new thread with that start function. The new thread is pushed on the
- * stack.
- */
- public synchronized void newThread() {
- check();
- lua_newthread();
- }
- /**
- * Resumes the thread at the specified stack index, popping the specified
- * number of arguments from the top of the stack and passing them to the
- * resumed thread. The method returns the number of values pushed on the
- * stack as the return values of the resumed thread.
- *
- * @param index
- * the stack index containing the thread
- * @param argCount
- * the number of arguments to pass
- * @return the number of values returned by the thread
- */
- public synchronized int resume(int index, int argCount) {
- check();
- return lua_resume(index, argCount);
- }
- /**
- * Returns the status of the thread at the specified stack index. If the
- * thread is in initial state of has finished its execution, the method
- * returns <code>0</code>. If the thread has yielded, the method returns
- * {@link #YIELD}. Other return values indicate errors for which an
- * exception has been thrown.
- *
- * @param index
- * the index
- * @return the status
- */
- public synchronized int status(int index) {
- check();
- return lua_status(index);
- }
- /**
- * Yields the running thread, popping the specified number of values from
- * the top of the stack and passing them as return values to the thread
- * which has resumed the running thread. The method must be used exclusively
- * at the exit point of Java functions, i.e.
- * <code>return luaState.yield(n)</code>.
- *
- * @param returnCount
- * the number of results to pass
- * @return the return value of the Java function
- */
- public synchronized int yield(int returnCount) {
- check();
- yield = true;
- return returnCount;
- }
- // -- Reference
- /**
- * Stores the value on top of the stack in the table at the specified index
- * and returns the integer key of the value in that table as a reference.
- * The value is popped from the stack.
- *
- * @param index
- * the stack index containing the table where to store the value
- * @return the reference integer key
- * @see #unref(int, int)
- */
- public synchronized int ref(int index) {
- check();
- return lua_ref(index);
- }
- /**
- * Removes a previously created reference from the table at the specified
- * index. The value is removed from the table and its integer key of the
- * reference is freed for reuse.
- *
- * @param index
- * the stack index containing the table where the value was
- * stored
- * @param reference
- * the reference integer key
- * @see #ref(int)
- */
- public synchronized void unref(int index, int reference) {
- check();
- lua_unref(index, reference);
- }
- // -- Optimization
- /**
- * Counts the number of entries in a table.
- *
- * <p>
- * The method provides optimized performance over a Java implementation of
- * the same functionality due to the reduced number of JNI transitions.
- * </p>
- *
- * @param index
- * the stack index containing the table
- * @return the number of entries in the table
- */
- public synchronized int tableSize(int index) {
- check();
- return lua_tablesize(index);
- }
- /**
- * Moves the specified number of sequential elements in a table used as an
- * array from one index to another.
- *
- * <p>
- * The method provides optimized performance over a Java implementation of
- * the same functionality due to the reduced number of JNI transitions.
- * </p>
- *
- * @param index
- * the stack index containing the table
- * @param from
- * the index to move from
- * @param to
- * the index to move to
- * @param count
- * the number of elements to move
- */
- public synchronized void tableMove(int index, int from, int to, int count) {
- check();
- lua_tablemove(index, from, to, count);
- }
- // -- Argument checking
- /**
- * Checks if a condition is true for the specified function argument. If
- * not, the method throws a Lua runtime exception with the specified error
- * message.
- *
- * @param index
- * the argument index
- * @param condition
- * the condition
- * @param msg
- * the error message
- */
- public synchronized void checkArg(int index, boolean condition, String msg) {
- check();
- if (!condition) {
- throw getArgException(index, msg);
- }
- }
- /**
- * Checks if the value of the specified function argument is a string or a
- * number. If so, the argument value is returned as a byte array. Otherwise,
- * the method throws a Lua runtime exception with a descriptive error
- * message.
- *
- * @param index
- * the argument index
- * @return the byte array value
- */
- public synchronized byte[] checkByteArray(int index) {
- check();
- if (!isString(index)) {
- throw getArgTypeException(index, LuaType.STRING);
- }
- return toByteArray(index);
- }
- /**
- * Checks if the value of the specified function argument is a string or a
- * number. If so, the argument value is returned as a byte array. If the
- * value of the specified argument is undefined or <code>nil</code>, the
- * method returns the specified default value. Otherwise, the method throws
- * a Lua runtime exception with a descriptive error message.
- *
- * @param index
- * the argument index
- * @param d
- * the default value
- * @return the string value, or the default value
- */
- public synchronized byte[] checkByteArray(int index, byte[] d) {
- check();
- if (isNoneOrNil(index)) {
- return d;
- }
- return checkByteArray(index);
- }
- /**
- * Checks if the value of the specified function argument is a string or a
- * number matching the name of one of the specified enum values. If so, the
- * argument value is returned as an enum value. Otherwise, the method throws
- * a Lua runtime exception with a descriptive error message.
- *
- * @param index
- * the argument index
- * @param values
- * the enum values
- * @return the string value
- * @since JNLua 1.0.0
- */
- public synchronized <T extends Enum<T>> T checkEnum(int index, T[] values) {
- check();
- return checkEnum(index, values, null);
- }
- /**
- * Checks if the value of the specified function argument is a string or a
- * number matching one of the specified enum values. If so, the argument
- * value is returned as an enum value. If the specified stack index is
- * non-valid or if its value is <code>nil</code>, the method returns the
- * specified default value. Otherwise, the method throws a Lua runtime
- * exception with a descriptive error message.
- *
- * @param index
- * the argument index
- * @param values
- * the enum values
- * @param d
- * the default value
- * @return the string value, or the default value
- * @since JNLua 1.0.0
- */
- public synchronized <T extends Enum<T>> T checkEnum(int index, T[] values,
- T d) {
- check();
- String s = d != null ? checkString(index, d.name())
- : checkString(index);
- for (int i = 0; i < values.length; i++) {
- if (values[i].name().equals(s)) {
- return values[i];
- }
- }
- throw getArgException(index, String.format("invalid option '%s'", s));
- }
- /**
- * Checks if the value of the specified function argument is a boolean. If
- * so, the argument value is returned as a boolean. Otherwise, the method
- * throws a Lua runtime exception with a descriptive error message.
- *
- * @param index
- * the argument index
- * @return the integer value
- */
- public synchronized boolean checkBoolean(int index) {
- check();
- if (!isBoolean(index)) {
- throw getArgTypeException(index, LuaType.BOOLEAN);
- }
- return toBoolean(index);
- }
- /**
- * Checks if the value of the specified function argument is a number or a
- * string convertible to a number. If so, the argument value is returned as
- * an integer. Otherwise, the method throws a Lua runtime exception with a
- * descriptive error message.
- *
- * @param index
- * the argument index
- * @return the integer value
- */
- public synchronized int checkInteger(int index) {
- check();
- Integer integer = toIntegerX(index);
- if (integer == null) {
- throw getArgTypeException(index, LuaType.NUMBER);
- }
- return integer.intValue();
- }
- /**
- * Checks if the value of the specified function argument is a number or a
- * string convertible to a number. If so, the argument value is returned as
- * an integer. If the specified stack index is non-valid or if its value is
- * <code>nil</code>, the method returns the specified default value.
- * Otherwise, the method throws a Lua runtime exception with a descriptive
- * error message.
- *
- * @param index
- * the argument index
- * @param d
- * the default value
- * @return the integer value, or the default value
- */
- public synchronized int checkInteger(int index, int d) {
- check();
- if (isNoneOrNil(index)) {
- return d;
- }
- return checkInteger(index);
- }
- /**
- * Checks if the value of the specified function argument is convertible to
- * a Java object of the specified type. If so, the argument value is
- * returned as a Java object of the specified type. Otherwise, the method
- * throws a Lua runtime exception with a descriptive error message.
- *
- * <p>
- * Note that the converter converts <code>nil</code> to <code>null</code>.
- * Therefore, the method may return <code>null</code> if the value is
- * <code>nil</code>.
- * </p>
- *
- * @param index
- * the argument index
- * @param clazz
- * the expected type
- * @return the Java object, or <code>null</code>
- */
- public synchronized <T> T checkJavaObject(int index, Class<T> clazz) {
- check();
- if (!isJavaObject(index, clazz)) {
- checkArg(
- index,
- false,
- String.format("%s expected, got %s",
- clazz.getCanonicalName(), typeName(index)));
- }
- return toJavaObject(index, clazz);
- }
- /**
- * Checks if the value of the specified function argument is convertible to
- * a Java object of the specified type. If so, the argument value is
- * returned as a Java object of the specified type. If the specified stack
- * index is non-valid or if its value is <code>nil</code>, the method
- * returns the specified default value. Otherwise, the method throws a Lua
- * runtime exception with a descriptive error message.
- *
- * @param index
- * the argument index
- * @param clazz
- * the expected class
- * @param d
- * the default value
- * @return the Java object, or the default value
- */
- public synchronized <T> T checkJavaObject(int index, Class<T> clazz, T d) {
- check();
- if (isNoneOrNil(index)) {
- return d;
- }
- return checkJavaObject(index, clazz);
- }
- /**
- * Checks if the value of the specified function argument is a number or a
- * string convertible to a number. If so, the argument value is returned as
- * a number. Otherwise, the method throws a Lua runtime exception with a
- * descriptive error message.
- *
- * @param index
- * the argument index
- * @return the number value
- */
- public synchronized double checkNumber(int index) {
- check();
- Double number = toNumberX(index);
- if (number == null) {
- throw getArgTypeException(index, LuaType.NUMBER);
- }
- return number.doubleValue();
- }
- /**
- * Checks if the value of the specified function argument is a number or a
- * string convertible to a number. If so, the argument value is returned as
- * a number. If the specified stack index is non-valid or if its value is
- * <code>nil</code>, the method returns the specified default value.
- * Otherwise, the method throws a Lua runtime exception with a descriptive
- * error message.
- *
- * @param index
- * the argument index
- * @param d
- * the default value
- * @return the number value, or the default value
- */
- public synchronized double checkNumber(int index, double d) {
- check();
- if (isNoneOrNil(index)) {
- return d;
- }
- return checkNumber(index);
- }
- /**
- * Checks if the value of the specified function argument is a string or a
- * number matching one of the specified options. If so, the index position
- * of the matched option is returned. Otherwise, the method throws a Lua
- * runtime exception with a descriptive error message.
- *
- * @param index
- * the argument index
- * @param options
- * the options
- * @return the index position of the matched option
- */
- public synchronized int checkOption(int index, String[] options) {
- check();
- return checkOption(index, options, null);
- }
- /**
- * Checks if the value of the specified function argument is a string or a
- * number matching one of the specified options. If so, the index position
- * of the matched option is returned. If the specified stack index is
- * non-valid or if its value is <code>nil</code>, the method matches the
- * specified default value. If no match is found, the method throws a Lua
- * runtime exception with a descriptive error message.
- *
- * @param index
- * the argument index
- * @param options
- * the options
- * @param d
- * the default value
- * @return the index position of the matched option
- */
- public synchronized int checkOption(int index, String[] options, String d) {
- check();
- String s = d != null ? checkString(index, d) : checkString(index);
- for (int i = 0; i < options.length; i++) {
- if (options[i].equals(s)) {
- return i;
- }
- }
- throw getArgException(index, String.format("invalid option '%s'", s));
- }
- /**
- * Checks if the value of the specified function argument is a string or a
- * number. If so, the argument value is returned as a string. Otherwise, the
- * method throws a Lua runtime exception with a descriptive error message.
- *
- * @param index
- * the argument index
- * @return the string value
- */
- public synchronized String checkString(int index) {
- check();
- if (!isString(index)) {
- throw getArgTypeException(index, LuaType.STRING);
- }
- return toString(index);
- }
- /**
- * Checks if the value of the specified function argument is a string or a
- * number. If so, the argument value is returned as a string. If the
- * specified stack index is non-valid or if its value is <code>nil</code>,
- * the method returns the specified default value. Otherwise, the method
- * throws a Lua runtime exception with a descriptive error message.
- *
- * @param index
- * the argument index
- * @param d
- * the default value
- * @return the string value, or the default value
- */
- public synchronized String checkString(int index, String d) {
- check();
- if (isNoneOrNil(index)) {
- return d;
- }
- return checkString(index);
- }
- /**
- * Checks if the value of the specified function argument is of the
- * specified type. If not, the method throws a Lua runtime exception with a
- * descriptive error message.
- *
- * @param index
- * the argument index
- * @param type
- * the type
- */
- public synchronized void checkType(int index, LuaType type) {
- check();
- if (type(index) != type) {
- throw getArgTypeException(index, type);
- }
- }
- // -- Proxy
- /**
- * Returns a proxy object for the Lua value at the specified index.
- *
- * @param index
- * the stack index containing the Lua value
- * @return the Lua value proxy
- */
- public synchronized LuaValueProxy getProxy(int index) {
- check();
- pushValue(index);
- return new LuaValueProxyImpl(ref(REGISTRYINDEX()));
- }
- /**
- * Returns a proxy object implementing the specified interface in Lua. The
- * table at the specified stack index contains the method names from the
- * interface as keys and the Lua functions implementing the interface
- * methods as values. The returned object always implements the
- * {@link LuaValueProxy} interface in addition to the specified interface.
- *
- * @param index
- * the stack index containing the table
- * @param interfaze
- * the interface
- * @return the proxy object
- */
- @SuppressWarnings("unchecked")
- public synchronized <T> T getProxy(int index, Class<T> interfaze) {
- check();
- return (T) getProxy(index, new Class<?>[] { interfaze });
- }
- /**
- * Returns a proxy object implementing the specified list of interfaces in
- * Lua. The table at the specified stack index contains the method names
- * from the interfaces as keys and the Lua functions implementing the
- * interface methods as values. The returned object always implements the
- * {@link LuaValueProxy} interface in addition to the specified interfaces.
- *
- * @param index
- * the stack index containing the table
- * @param interfaces
- * the interfaces
- * @return the proxy object
- */
- public synchronized LuaValueProxy getProxy(int index, Class<?>[] interfaces) {
- check();
- pushValue(index);
- if (!isTable(index)) {
- throw new IllegalArgumentException(String.format(
- "index %d is not a table", index));
- }
- Class<?>[] allInterfaces = new Class<?>[interfaces.length + 1];
- System.arraycopy(interfaces, 0, allInterfaces, 0, interfaces.length);
- allInterfaces[allInterfaces.length - 1] = LuaValueProxy.class;
- int reference = ref(REGISTRYINDEX());
- try {
- Object proxy = Proxy.newProxyInstance(classLoader, allInterfaces,
- new LuaInvocationHandler(reference));
- reference = -1;
- return (LuaValueProxy) proxy;
- } finally {
- if (reference >= 0) {
- unref(REGISTRYINDEX(), reference);
- }
- }
- }
- // -- Private methods
- /**
- * Returns whether this Lua state is open.
- */
- private boolean isOpenInternal() {
- return luaState != 0L;
- }
- /**
- * Closes this Lua state.
- */
- private void closeInternal() {
- if (isOpenInternal()) {
- lua_close(ownState);
- if (isOpenInternal()) {
- throw new IllegalStateException("cannot close");
- }
- }
- }
- /**
- * Checks this Lua state.
- */
- private void check() {
- // Check open
- if (!isOpenInternal()) {
- throw new IllegalStateException("Lua state is closed");
- }
- // Check proxy queue
- LuaValueProxyRef luaValueProxyRef;
- while ((luaValueProxyRef = (LuaValueProxyRef) proxyQueue.poll()) != null) {
- proxySet.remove(luaValueProxyRef);
- lua_unref(REGISTRYINDEX(), luaValueProxyRef.getReference());
- }
- }
- /**
- * Creates a Lua runtime exception to indicate an argument type error.
- */
- private LuaRuntimeException getArgTypeException(int index, LuaType type) {
- final LuaType have = type(index);
- return getArgException(index,
- String.format("%s expected, got %s", type.toString()
- .toLowerCase(), have != null ? type(index).toString().toLowerCase() : "none"));
- }
- /**
- * Creates a Lua runtime exception to indicate an argument error.
- *
- * @param extraMsg
- * @return
- */
- private LuaRuntimeException getArgException(int index, String extraMsg) {
- check();
- // Get execution point
- String name = null, nameWhat = null;
- LuaDebug luaDebug = lua_getstack(0);
- if (luaDebug != null) {
- lua_getinfo("n", luaDebug);
- name = luaDebug.getName();
- nameWhat = luaDebug.getNameWhat();
- }
- // Adjust for methods
- if ("method".equals(nameWhat)) {
- index--;
- }
- // Format message
- String msg;
- String argument = index > 0 ? String.format("argument #%d", index)
- : "self argument";
- if (name != null) {
- msg = String
- .format("bad %s to '%s' (%s)", argument, name, extraMsg);
- } else {
- msg = String.format("bad %s (%s)", argument, extraMsg);
- }
- return new LuaRuntimeException(msg);
- }
- /**
- * Validates a value specified as the new maximum allowed memory use. This
- * is used in particular to validate values passed to the constructor.
- *
- * @param value
- * the value to validate
- * @return the value itself
- */
- private static int validateMemory(int value) {
- if (value < 1) {
- throw new IllegalArgumentException("Maximum memory must be larger than zero.");
- }
- return value;
- }
- // -- Native methods
- public static native int lua_registryindex();
- public static native String lua_version();
- protected native void lua_newstate(int apiversion, long luaState);
- protected native void lua_close(boolean ownState);
- protected native int lua_gc(int what, int data);
- protected native void lua_openlib(int lib);
- protected native void lua_load(InputStream inputStream, String chunkname,
- String mode) throws IOException;
- protected native void lua_dump(OutputStream outputStream) throws IOException;
- protected native void lua_pcall(int nargs, int nresults);
- protected native void lua_getglobal(String name);
- protected native void lua_setglobal(String name);
- protected native void lua_pushboolean(int b);
- protected native void lua_pushbytearray(byte[] b);
- protected native void lua_pushinteger(int n);
- protected native void lua_pushjavafunction(JavaFunction f);
- protected native void lua_pushjavaobject(Object object);
- protected native void lua_pushnil();
- protected native void lua_pushnumber(double n);
- protected native void lua_pushstring(String s);
- protected native int lua_isboolean(int index);
- protected native int lua_iscfunction(int index);
- protected native int lua_isfunction(int index);
- protected native int lua_isjavafunction(int index);
- protected native int lua_isjavaobject(int index);
- protected native int lua_isnil(int index);
- protected native int lua_isnone(int index);
- protected native int lua_isnoneornil(int index);
- protected native int lua_isnumber(int index);
- protected native int lua_isstring(int index);
- protected native int lua_istable(int index);
- protected native int lua_isthread(int index);
- protected native int lua_compare(int index1, int index2, int operator);
- protected native int lua_rawequal(int index1, int index2);
- protected native int lua_rawlen(int index);
- protected native int lua_toboolean(int index);
- protected native byte[] lua_tobytearray(int index);
- protected native int lua_tointeger(int index);
- protected native Integer lua_tointegerx(int index);
- protected native JavaFunction lua_tojavafunction(int index);
- protected native Object lua_tojavaobject(int index);
- protected native double lua_tonumber(int index);
- protected native Double lua_tonumberx(int index);
- protected native long lua_topointer(int index);
- protected native String lua_tostring(int index);
- protected native int lua_type(int index);
- protected native int lua_absindex(int index);
- protected native int lua_arith(int operator);
- protected native void lua_concat(int n);
- protected native int lua_copy(int fromIndex, int toIndex);
- protected native int lua_gettop();
- protected native void lua_len(int index);
- protected native void lua_insert(int index);
- protected native void lua_pop(int n);
- protected native void lua_pushvalue(int index);
- protected native void lua_remove(int index);
- protected native void lua_replace(int index);
- protected native void lua_settop(int index);
- protected native void lua_createtable(int narr, int nrec);
- protected native int lua_getsubtable(int idx, String fname);
- protected native void lua_gettable(int index);
- protected native void lua_getfield(int index, String k);
- protected native void lua_newtable();
- protected native int lua_next(int index);
- protected native void lua_rawget(int index);
- protected native void lua_rawgeti(int index, int n);
- protected native void lua_rawset(int index);
- protected native void lua_rawseti(int index, int n);
- protected native void lua_settable(int index);
- protected native void lua_setfield(int index, String k);
- protected native int lua_getmetatable(int index);
- protected native void lua_setmetatable(int index);
- protected native int lua_getmetafield(int index, String k);
- protected native void lua_newthread();
- protected native int lua_resume(int index, int nargs);
- protected native int lua_status(int index);
- protected native int lua_getcoroutinemem();
- protected native int lua_ref(int index);
- protected native void lua_unref(int index, int ref);
- protected native LuaDebug lua_getstack(int level);
- protected native int lua_getinfo(String what, LuaDebug ar);
- protected native int lua_tablesize(int index);
- protected native void lua_tablemove(int index, int from, int to, int count);
- // -- Enumerated types
- /**
- * Represents a Lua library.
- */
- public enum Library {
- /*
- * The order of the libraries follows the definition in linit.c.
- */
- /**
- * The base library.
- */
- BASE,
- /**
- * The package library.
- */
- PACKAGE,
- /**
- * The coroutine library.
- *
- * @since JNLua 1.0.0
- */
- COROUTINE,
- /**
- * The table library.
- */
- TABLE,
- /**
- * The IO library.
- */
- IO,
- /**
- * The OS library.
- */
- OS,
- /**
- * The string library.
- */
- STRING,
- /**
- * The bit32 library.
- *
- * @since JNLua 1.0.0
- */
- BIT32,
- /**
- * The math library.
- */
- MATH,
- /**
- * The debug library.
- */
- DEBUG,
- /**
- * The persistence library.
- */
- ERIS,
- /**
- * The UTF-8 library.
- *
- * @since JNLua 1.1.0
- */
- UTF8,
- /**
- * The Java library.
- */
- JAVA {
- @Override
- void open(LuaState luaState) {
- JavaModule.getInstance().open(luaState);
- }
- };
- // -- Methods
- /**
- * Opens this library.
- */
- void open(LuaState luaState) {
- luaState.lua_openlib(ordinal());
- }
- }
- /**
- * Represents a Lua garbage collector action. Please see the Lua Reference
- * Manual for an explanation of these actions.
- */
- public enum GcAction {
- /**
- * Stop.
- */
- STOP,
- /**
- * Restart.
- */
- RESTART,
- /**
- * Collect.
- */
- COLLECT,
- /**
- * Count memory in kilobytes.
- */
- COUNT,
- /**
- * Count reminder in bytes.
- */
- COUNTB,
- /**
- * Step.
- */
- STEP,
- /**
- * Set pause.
- */
- SETPAUSE,
- /**
- * Set step multiplier.
- */
- SETSTEPMUL,
- /**
- * Undocumented.
- *
- * @since JNLua 1.0.0
- */
- SETMAJORINC,
- /**
- * Returns whether the collector is running (i.e. not stopped).
- *
- * @since JNLua 1.0.0
- */
- ISRUNNING,
- /**
- * Changes the collector to the generational mode.
- *
- * @since JNLua 1.0.0
- */
- GEN,
- /**
- * Changes the collector to the incremental mode.
- *
- * @since JNLua 1.0.0
- */
- INC
- }
- /**
- * Represents a Lua arithmetic operator. Please see the Lua Reference Manual
- * for an explanation of these operators.
- *
- * @since JNLua 1.0.0
- */
- public enum ArithOperator {
- /**
- * Addition operator.
- */
- ADD,
- /**
- * Subtraction operator.
- */
- SUB,
- /**
- * Multiplication operator.
- */
- MUL,
- /**
- * Division operator.
- */
- DIV,
- /**
- * Modulo operator.
- */
- MOD,
- /**
- * Exponentiation operator.
- */
- POW,
- /**
- * Mathematical negation operator.
- */
- UNM
- }
- /**
- * Represents a Lua relational operator. Please see the Lua Reference Manual
- * for an explanation of these operators.
- *
- * @since JNLua 1.0.0
- */
- public enum RelOperator {
- /**
- * Equality operator.
- */
- EQ,
- /**
- * Less than operator.
- */
- LT,
- /**
- * Less or equal operator.
- */
- LE
- }
- // -- Nested types
- /**
- * Phantom reference to a Lua value proxy for pre-mortem cleanup.
- */
- private static class LuaValueProxyRef extends
- PhantomReference<LuaValueProxyImpl> {
- // -- State
- private int reference;
- // --Construction
- /**
- * Creates a new instance.
- */
- public LuaValueProxyRef(LuaValueProxyImpl luaProxyImpl, int reference) {
- super(luaProxyImpl, luaProxyImpl.getLuaState().proxyQueue);
- this.reference = reference;
- }
- // -- Properties
- /**
- * Returns the reference.
- */
- public int getReference() {
- return reference;
- }
- }
- /**
- * Lua value proxy implementation.
- */
- private class LuaValueProxyImpl implements LuaValueProxy {
- // -- State
- private int reference;
- // -- Construction
- /**
- * Creates a new instance.
- */
- public LuaValueProxyImpl(int reference) {
- this.reference = reference;
- proxySet.add(new LuaValueProxyRef(this, reference));
- }
- // -- LuaProxy methods
- @Override
- public LuaState getLuaState() {
- return LuaState.this;
- }
- @Override
- public void pushValue() {
- synchronized (LuaState.this) {
- rawGet(REGISTRYINDEX(), reference);
- }
- }
- }
- /**
- * Invocation handler for implementing Java interfaces in Lua.
- */
- private class LuaInvocationHandler extends LuaValueProxyImpl implements
- InvocationHandler {
- // -- Construction
- /**
- * Creates a new instance.
- */
- public LuaInvocationHandler(int reference) {
- super(reference);
- }
- // -- InvocationHandler methods
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- // Handle LuaProxy methods
- if (method.getDeclaringClass() == LuaValueProxy.class) {
- return method.invoke(this, args);
- }
- // Handle Lua calls
- synchronized (LuaState.this) {
- pushValue();
- getField(-1, method.getName());
- if (!isFunction(-1)) {
- pop(2);
- throw new UnsupportedOperationException(method.getName());
- }
- insert(-2);
- int argCount = args != null ? args.length : 0;
- for (int i = 0; i < argCount; i++) {
- pushJavaObject(args[i]);
- }
- int retCount = method.getReturnType() != Void.TYPE ? 1 : 0;
- call(argCount + 1, retCount);
- try {
- return retCount == 1 ? LuaState.this.toJavaObject(-1,
- method.getReturnType()) : null;
- } finally {
- if (retCount == 1) {
- pop(1);
- }
- }
- }
- }
- }
- /**
- * Lua debug structure.
- */
- protected static class LuaDebug {
- /**
- * The <code>lua_Debug</code> pointer on the JNI side. <code>0</code>
- * implies that the activation record has been freed. The field is
- * modified exclusively on the JNI side and must not be touched on the
- * Java side.
- */
- private long luaDebug;
- /**
- * Ensures proper finalization of this Lua debug structure.
- */
- private Object finalizeGuardian;
- /**
- * Creates a new instance.
- */
- protected LuaDebug(long luaDebug, boolean ownDebug) {
- this.luaDebug = luaDebug;
- if (ownDebug) {
- finalizeGuardian = new Object() {
- @Override
- public void finalize() {
- synchronized (LuaDebug.this) {
- lua_debugfree();
- }
- }
- };
- }
- }
- // -- Properties
- /**
- * Returns a reasonable name for the function given by this activation
- * record, or <code>null</code> if none is found.
- */
- public String getName() {
- return lua_debugname();
- }
- /**
- * Explains the name of the function given by this activation record.
- */
- public String getNameWhat() {
- return lua_debugnamewhat();
- }
- // -- Native methods
- protected native void lua_debugfree();
- protected native String lua_debugname();
- protected native String lua_debugnamewhat();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment