Add javadoc content to source files.
This commit is contained in:
@@ -24,21 +24,49 @@ package org.luaj.vm2;
|
||||
|
||||
/**
|
||||
* String buffer for use in string library methods, optimized for production
|
||||
* of StrValue instances.
|
||||
* of StrValue instances.
|
||||
* <p>
|
||||
* The buffer can begin initially as a wrapped {@link LuaValue}
|
||||
* and only when concatenation actually occurs are the bytes first copied.
|
||||
* <p>
|
||||
* To convert back to a {@link LuaValue} again,
|
||||
* the function {@link Buffer#value()} is used.
|
||||
* @see LuaValue
|
||||
* @see LuaValue#buffer()
|
||||
* @see LuaString
|
||||
*/
|
||||
public final class Buffer {
|
||||
|
||||
/** Default capacity for a buffer: 64 */
|
||||
private static final int DEFAULT_CAPACITY = 64;
|
||||
|
||||
/** Shared static array with no bytes */
|
||||
private static final byte[] NOBYTES = {};
|
||||
|
||||
/** Bytes in this buffer */
|
||||
private byte[] bytes;
|
||||
|
||||
/** Length of this buffer */
|
||||
private int length;
|
||||
|
||||
/** Offset into the byte array */
|
||||
private int offset;
|
||||
|
||||
/** Value of this buffer, when not represented in bytes */
|
||||
private LuaValue value;
|
||||
|
||||
/**
|
||||
* Create buffer with default capacity
|
||||
* @see #DEFAULT_CAPACITY
|
||||
*/
|
||||
public Buffer() {
|
||||
this(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create buffer with specified initial capacity
|
||||
* @param initialCapacity the initial capacity
|
||||
*/
|
||||
public Buffer( int initialCapacity ) {
|
||||
bytes = new byte[ initialCapacity ];
|
||||
length = 0;
|
||||
@@ -46,16 +74,28 @@ public final class Buffer {
|
||||
value = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create buffer with specified initial value
|
||||
* @param value the initial value
|
||||
*/
|
||||
public Buffer(LuaValue value) {
|
||||
bytes = NOBYTES;
|
||||
length = offset = 0;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get buffer contents as a {@link LuaValue}
|
||||
* @return value as a {@link LuaValue}, converting as necessary
|
||||
*/
|
||||
public LuaValue value() {
|
||||
return value != null? value: this.tostring();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set buffer contents as a {@link LuaValue}
|
||||
* @param value value to set
|
||||
*/
|
||||
public Buffer setvalue(LuaValue value) {
|
||||
bytes = NOBYTES;
|
||||
offset = length = 0;
|
||||
@@ -63,30 +103,54 @@ public final class Buffer {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the buffer to a {@link LuaString}
|
||||
* @return the value as a {@link LuaString}
|
||||
*/
|
||||
public final LuaString tostring() {
|
||||
realloc( length, 0 );
|
||||
return LuaString.valueOf( bytes, offset, length );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the buffer to a Java String
|
||||
* @return the value as a Java String
|
||||
*/
|
||||
public String tojstring() {
|
||||
return value().tojstring();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the buffer to a Java String
|
||||
* @return the value as a Java String
|
||||
*/
|
||||
public String toString() {
|
||||
return tojstring();
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a single byte to the buffer.
|
||||
* @return {@code this} to allow call chaining
|
||||
*/
|
||||
public final Buffer append( byte b ) {
|
||||
makeroom( 0, 1 );
|
||||
bytes[ offset + length++ ] = b;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a {@link LuaValue} to the buffer.
|
||||
* @return {@code this} to allow call chaining
|
||||
*/
|
||||
public final Buffer append( LuaValue val ) {
|
||||
append( val.strvalue() );
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a {@link LuaString} to the buffer.
|
||||
* @return {@code this} to allow call chaining
|
||||
*/
|
||||
public final Buffer append( LuaString str ) {
|
||||
final int n = str.m_length;
|
||||
makeroom( 0, n );
|
||||
@@ -95,6 +159,12 @@ public final class Buffer {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a Java String to the buffer.
|
||||
* The Java string will be converted to bytes using the UTF8 encoding.
|
||||
* @return {@code this} to allow call chaining
|
||||
* @see LuaString#encodeToUtf8(char[], byte[], int)
|
||||
*/
|
||||
public final Buffer append( String str ) {
|
||||
char[] chars = str.toCharArray();
|
||||
final int n = LuaString.lengthAsUtf8( chars );
|
||||
@@ -104,18 +174,36 @@ public final class Buffer {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Concatenate this buffer onto a {@link LuaValue}
|
||||
* @param lhs the left-hand-side value onto which we are concatenating {@code this}
|
||||
* @return {@link Buffer} for use in call chaining.
|
||||
*/
|
||||
public Buffer concatTo(LuaValue lhs) {
|
||||
return setvalue(lhs.concat(value()));
|
||||
}
|
||||
|
||||
/** Concatenate this buffer onto a {@link LuaString}
|
||||
* @param lhs the left-hand-side value onto which we are concatenating {@code this}
|
||||
* @return {@link Buffer} for use in call chaining.
|
||||
*/
|
||||
public Buffer concatTo(LuaString lhs) {
|
||||
return value!=null&&!value.isstring()? setvalue(lhs.concat(value)): prepend(lhs);
|
||||
}
|
||||
|
||||
/** Concatenate this buffer onto a {@link LuaNumber}
|
||||
* <p>
|
||||
* The {@link LuaNumber} will be converted to a string before concatenating.
|
||||
* @param lhs the left-hand-side value onto which we are concatenating {@code this}
|
||||
* @return {@link Buffer} for use in call chaining.
|
||||
*/
|
||||
public Buffer concatTo(LuaNumber lhs) {
|
||||
return value!=null&&!value.isstring()? setvalue(lhs.concat(value)): prepend(lhs.strvalue());
|
||||
}
|
||||
|
||||
/** Concatenate bytes from a {@link LuaString} onto the front of this buffer
|
||||
* @param s the left-hand-side value which we will concatenate onto the front of {@code this}
|
||||
* @return {@link Buffer} for use in call chaining.
|
||||
*/
|
||||
public Buffer prepend(LuaString s) {
|
||||
int n = s.m_length;
|
||||
makeroom( n, 0 );
|
||||
@@ -126,6 +214,10 @@ public final class Buffer {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Ensure there is enough room before and after the bytes.
|
||||
* @param nbefore number of unused bytes which must precede the data after this completes
|
||||
* @param nafter number of unused bytes which must follow the data after this completes
|
||||
*/
|
||||
public final void makeroom( int nbefore, int nafter ) {
|
||||
if ( value != null ) {
|
||||
LuaString s = value.strvalue();
|
||||
@@ -141,6 +233,10 @@ public final class Buffer {
|
||||
}
|
||||
}
|
||||
|
||||
/** Reallocate the internal storage for the buffer
|
||||
* @param newSize the size of the buffer to use
|
||||
* @param newOffset the offset to use
|
||||
*/
|
||||
private final void realloc( int newSize, int newOffset ) {
|
||||
if ( newSize != bytes.length ) {
|
||||
byte[] newBytes = new byte[ newSize ];
|
||||
|
||||
@@ -25,8 +25,14 @@ import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/*
|
||||
** Loader to load compiled function prototypes
|
||||
/**
|
||||
* Class to manage loading of {@link Prototype} instances.
|
||||
* <p>
|
||||
* @see LuaCompiler
|
||||
* @see LuaClosure
|
||||
* @see LuaFunction
|
||||
* @see LoadState#compiler
|
||||
* @see LoadState#load(InputStream, String, LuaValue)
|
||||
*/
|
||||
public class LoadState {
|
||||
|
||||
@@ -53,7 +59,12 @@ public class LoadState {
|
||||
public static final int LUA_TTHREAD = 8;
|
||||
public static final int LUA_TVALUE = 9;
|
||||
|
||||
/** Interface for the compiler, if it is installed. */
|
||||
/** Interface for the compiler, if it is installed.
|
||||
* <p>
|
||||
* See the {@link LuaClosure} documentation for examples of how to use the compiler.
|
||||
* @see LuaClosure
|
||||
* @see #load(InputStream, String, LuaValue)
|
||||
* */
|
||||
public interface LuaCompiler {
|
||||
|
||||
/** Load into a Closure or LuaFunction from a Stream and initializes the environment
|
||||
@@ -106,6 +117,9 @@ public class LoadState {
|
||||
private byte[] buf = new byte[512];
|
||||
|
||||
|
||||
/** 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?
|
||||
@@ -113,6 +127,9 @@ public class LoadState {
|
||||
(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 )
|
||||
@@ -132,7 +149,9 @@ public class LoadState {
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
/** Load a long value from the input stream
|
||||
* @return the long value laoded.
|
||||
**/
|
||||
long loadInt64() throws IOException {
|
||||
int a,b;
|
||||
if ( this.luacLittleEndian ) {
|
||||
@@ -145,6 +164,9 @@ public class LoadState {
|
||||
return (((long)b)<<32) | (((long)a)&0xffffffffL);
|
||||
}
|
||||
|
||||
/** Load a lua strin gvalue from the input stream
|
||||
* @return the {@link LuaString} value laoded.
|
||||
**/
|
||||
LuaString loadString() throws IOException {
|
||||
int size = loadInt();
|
||||
if ( size == 0 )
|
||||
@@ -154,6 +176,11 @@ public class LoadState {
|
||||
return LuaString.valueOf( bytes, 0, bytes.length - 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert bits in a long value to a {@link LuaValue}.
|
||||
* @param bits long value containing the bits
|
||||
* @return {@link LuaInteger} or {@link LuaDouble} whose value corresponds to the bits provided.
|
||||
*/
|
||||
public static LuaValue longBitsToLuaNumber( long bits ) {
|
||||
if ( ( bits & ( ( 1L << 63 ) - 1 ) ) == 0L ) {
|
||||
return LuaValue.ZERO;
|
||||
@@ -174,6 +201,11 @@ public class LoadState {
|
||||
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() );
|
||||
@@ -182,6 +214,11 @@ public class LoadState {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@@ -215,6 +252,11 @@ public class LoadState {
|
||||
f.p = protos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the debug infor for a function prototype
|
||||
* @param f the function Prototype
|
||||
* @throws IOException if there is an i/o exception
|
||||
*/
|
||||
void loadDebug( Prototype f ) throws IOException {
|
||||
f.lineinfo = loadIntArray();
|
||||
int n = loadInt();
|
||||
@@ -233,6 +275,12 @@ public class LoadState {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a function prototype from the input stream
|
||||
* @param p name of the source
|
||||
* @return {@link Prototype} instance that was loaded
|
||||
* @throws IOException
|
||||
*/
|
||||
public Prototype loadFunction(LuaString p) throws IOException {
|
||||
Prototype f = new Prototype();
|
||||
// this.L.push(f);
|
||||
@@ -257,6 +305,10 @@ public class LoadState {
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the lua chunk header values.
|
||||
* @throws IOException if an i/o exception occurs.
|
||||
*/
|
||||
public void loadHeader() throws IOException {
|
||||
luacVersion = is.readByte();
|
||||
luacFormat = is.readByte();
|
||||
@@ -268,6 +320,15 @@ public class LoadState {
|
||||
luacNumberFormat = is.readByte();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load lua in either binary or text form from an input stream.
|
||||
* @param firstByte the first byte of the input stream
|
||||
* @param stream InputStream to read, after having read the first byte already
|
||||
* @param name Name to apply to the loaded chunk
|
||||
* @return {@link Prototype} that was loaded
|
||||
* @throws IllegalArgumentException if the signature is bac
|
||||
* @throws IOException if an IOException occurs
|
||||
*/
|
||||
public static LuaFunction load( InputStream stream, String name, LuaValue env ) throws IOException {
|
||||
if ( compiler != null )
|
||||
return compiler.load(stream, name, env);
|
||||
@@ -280,6 +341,15 @@ public class LoadState {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load lua thought to be a binary chunk from its first byte from an input stream.
|
||||
* @param firstByte the first byte of the input stream
|
||||
* @param stream InputStream to read, after having read the first byte already
|
||||
* @param name Name to apply to the loaded chunk
|
||||
* @return {@link Prototype} that was loaded
|
||||
* @throws IllegalArgumentException if the signature is bac
|
||||
* @throws IOException if an IOException occurs
|
||||
*/
|
||||
public static Prototype loadBinaryChunk( int firstByte, InputStream stream, String name ) throws IOException {
|
||||
|
||||
// check rest of signature
|
||||
@@ -306,6 +376,11 @@ public class LoadState {
|
||||
return s.loadFunction( LuaString.valueOf(sname) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a source name from a supplied chunk name
|
||||
* @param name String name that appears in the chunk
|
||||
* @return source file name
|
||||
*/
|
||||
public static String getSourceName(String name) {
|
||||
String sname = name;
|
||||
if ( name.startsWith("@") || name.startsWith("=") )
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
* Copyright (c) 2009-2011 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
|
||||
@@ -21,11 +21,25 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
/**
|
||||
* Data class to hold debug information relatign to local variables for a {@link Prototype}
|
||||
*/
|
||||
public class LocVars {
|
||||
/** The local variable name */
|
||||
public LuaString varname;
|
||||
|
||||
/** The instruction offset when the variable comes into scope */
|
||||
public int startpc;
|
||||
|
||||
/** The instruction offset when the variable goes out of scope */
|
||||
public int endpc;
|
||||
|
||||
/**
|
||||
* Construct a LocVars instance.
|
||||
* @param varname The local variable name
|
||||
* @param startpc The instruction offset when the variable comes into scope
|
||||
* @param endpc The instruction offset when the variable goes out of scope
|
||||
*/
|
||||
public LocVars(LuaString varname, int startpc, int endpc) {
|
||||
this.varname = varname;
|
||||
this.startpc = startpc;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
* Copyright (c) 2009-2011 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
|
||||
@@ -23,7 +23,10 @@ package org.luaj.vm2;
|
||||
|
||||
|
||||
/**
|
||||
* Constants for lua limits and opcodes
|
||||
* Constants for lua limits and opcodes.
|
||||
* <p>
|
||||
* This is a direct translation of C lua distribution header file constants
|
||||
* for bytecode creation and processing.
|
||||
*/
|
||||
public class Lua {
|
||||
/** version is supplied by ant build task */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
* Copyright (c) 2009-2011 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
|
||||
@@ -21,13 +21,36 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
/**
|
||||
* Extension of {@link LuaValue} which can hold a Java boolean as its value.
|
||||
* <p>
|
||||
* These instance are not instantiated directly by clients.
|
||||
* Instead, there are exactly twon instances of this class,
|
||||
* {@link LuaValue#TRUE} and {@link LuaValue#FALSE}
|
||||
* representing the lua values {@code true} and {@link false}.
|
||||
* The function {@link LuaValue#valueOf(boolean)} will always
|
||||
* return one of these two values.
|
||||
* <p>
|
||||
* Any {@link LuaValue} can be converted to its equivalent
|
||||
* boolean representation using {@link LuaValue#toboolean()}
|
||||
* <p>
|
||||
* @see LuaValue
|
||||
* @see LuaValue#valueOf(boolean)
|
||||
* @see LuaValue#TRUE
|
||||
* @see LuaValue#FALSE
|
||||
*/
|
||||
public final class LuaBoolean extends LuaValue {
|
||||
|
||||
/** The singleton instance representing lua {@code true} */
|
||||
static final LuaBoolean _TRUE = new LuaBoolean(true);
|
||||
|
||||
/** The singleton instance representing lua {@code false} */
|
||||
static final LuaBoolean _FALSE = new LuaBoolean(false);
|
||||
|
||||
/** Shared static metatable for boolean values represented in lua. */
|
||||
public static LuaValue s_metatable;
|
||||
|
||||
|
||||
/** The value of the boolean */
|
||||
public final boolean v;
|
||||
|
||||
LuaBoolean(boolean b) {
|
||||
@@ -50,6 +73,10 @@ public final class LuaBoolean extends LuaValue {
|
||||
return v ? FALSE : LuaValue.TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the boolean value for this boolean
|
||||
* @return value as a Java boolean
|
||||
*/
|
||||
public boolean booleanValue() {
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,74 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.luaj.vm2.LoadState.LuaCompiler;
|
||||
import org.luaj.vm2.compiler.LuaC;
|
||||
import org.luaj.vm2.lib.DebugLib;
|
||||
|
||||
/**
|
||||
* Extension of {@link LuaFunction} which executes lua bytecode.
|
||||
* <p>
|
||||
* A {@link LuaClosure} is a combination of a {@link Prototype}
|
||||
* and a {@link LuaValue} to use as an environment for execution.
|
||||
* <p>
|
||||
* There are three main ways {@link LuaClosure} instances are created:
|
||||
* <ul>
|
||||
* <li>Construct an instance using {@link #LuaClosure(Prototype, LuaValue)}</li>
|
||||
* <li>Construct it indirectly by loading a chunk via {@link LuaCompiler#load(java.io.InputStream, String, LuaValue)}
|
||||
* <li>Execute the lua bytecode {@link Lua#OP_CLOSURE} as part of bytecode processing
|
||||
* </ul>
|
||||
* <p>
|
||||
* To construct it directly, the {@link Prototype} is typically created via a compiler such as {@link LuaC}:
|
||||
* <pre> {@code
|
||||
* InputStream is = new ByteArrayInputStream("print('hello,world').getBytes());
|
||||
* Prototype p = LuaC.instance.compile(is, "script");
|
||||
* LuaValue _G = JsePlatform.standardGlobals()
|
||||
* LuaClosure f = new LuaClosure(p, _G);
|
||||
* }</pre>
|
||||
* <p>
|
||||
* To construct it indirectly, the {@link LuaC} compiler may be used,
|
||||
* which implements the {@link LuaCompiler} interface:
|
||||
* <pre> {@code
|
||||
* LuaFunction f = LuaC.instance.load(is, "script", _G);
|
||||
* }</pre>
|
||||
* <p>
|
||||
* Typically, a closure that has just been loaded needs to be initialized by executing it,
|
||||
* and its return value can be saved if needed:
|
||||
* <pre> {@code
|
||||
* LuaValue r = f.call();
|
||||
* _G.set( "mypkg", r )
|
||||
* }</pre>
|
||||
* <p>
|
||||
* In the preceding, the loaded value is typed as {@link LuaFunction}
|
||||
* to allow for the possibility of other compilers such as {@link LuaJC}
|
||||
* producing {@link LuaFunction} directly without
|
||||
* creating a {@link Prototype} or {@link LuaClosure}.
|
||||
* <p>
|
||||
* Since a {@link LuaClosure} is a {@link LuaFunction} which is a {@link LuaValue},
|
||||
* all the value operations can be used directly such as:
|
||||
* <ul>
|
||||
* <li>{@link LuaValue#setfenv(LuaValue)}</li>
|
||||
* <li>{@link LuaValue#call()}</li>
|
||||
* <li>{@link LuaValue#call(LuaValue)}</li>
|
||||
* <li>{@link LuaValue#invoke()}</li>
|
||||
* <li>{@link LuaValue#invoke(Varargs)}</li>
|
||||
* <li>{@link LuaValue#method(String)}</li>
|
||||
* <li>{@link LuaValue#method(String,LuaValue)}</li>
|
||||
* <li>{@link LuaValue#invokemethod(String)}</li>
|
||||
* <li>{@link LuaValue#invokemethod(String,Varargs)}</li>
|
||||
* <li> ...</li>
|
||||
* </ul>
|
||||
* @see LuaValue
|
||||
* @see LuaFunction
|
||||
* @see LuaValue#isclosure()
|
||||
* @see LuaValue#checkclosure()
|
||||
* @see LuaValue#optclosure(LuaClosure)
|
||||
* @see LoadState
|
||||
* @see LoadState#compiler
|
||||
*/
|
||||
public class LuaClosure extends LuaFunction {
|
||||
private static final UpValue[] NOUPVALUES = new UpValue[0];
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
* Copyright (c) 2009-2011 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
|
||||
@@ -25,17 +25,25 @@ import org.luaj.vm2.lib.DebugLib;
|
||||
|
||||
/**
|
||||
* RuntimeException that is thrown and caught in response to a lua error.
|
||||
* This error does not indicate any problem with the normal functioning
|
||||
* of the Lua VM, but rather indicates that the lua script being interpreted
|
||||
* has encountered a lua error, eigher via LuaState.error() or lua error() calls.
|
||||
*
|
||||
* <p>
|
||||
* {@link LuaError} is used wherever a lua call to {@code error()}
|
||||
* would be used within a script.
|
||||
* <p>
|
||||
* Since it is an unchecked exception inheriting from {@link RuntimeException},
|
||||
* Java method signatures do notdeclare this exception, althoug it can
|
||||
* be thrown on almost any luaj Java operation.
|
||||
* This is analagous to the fact that any lua script can throw a lua error at any time.
|
||||
* <p>
|
||||
*/
|
||||
public class LuaError extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String traceback;
|
||||
|
||||
/** Run the error hook if there is one */
|
||||
/**
|
||||
* Run the error hook if there is one
|
||||
* @param msg the message to use in error hook processing.
|
||||
* */
|
||||
private static String errorHook(String msg) {
|
||||
LuaThread thread = LuaThread.getRunning();
|
||||
if ( thread.err != null ) {
|
||||
@@ -54,11 +62,10 @@ public class LuaError extends RuntimeException {
|
||||
|
||||
private Throwable cause;
|
||||
|
||||
/**
|
||||
* Construct a LuaErrorException in response to a Throwable that was caught
|
||||
* indicating a problem with the VM rather than the lua code.
|
||||
*
|
||||
* All errors generated from lua code should throw LuaError(String) instead.
|
||||
/** Construct LuaError when a program exception occurs.
|
||||
* <p>
|
||||
* All errors generated from lua code should throw LuaError(String) instead.
|
||||
* @param cause the Throwable that caused the error, if known.
|
||||
*/
|
||||
public LuaError(Throwable cause) {
|
||||
super( errorHook( addFileLine( "vm error: "+cause ) ) );
|
||||
@@ -67,8 +74,7 @@ public class LuaError extends RuntimeException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a LuaError with a specific message indicating a problem
|
||||
* within the lua code itself such as an argument type error.
|
||||
* Construct a LuaError with a specific message.
|
||||
*
|
||||
* @param message message to supply
|
||||
*/
|
||||
@@ -78,6 +84,7 @@ public class LuaError extends RuntimeException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a LuaError with a message, and level to draw line number information from.
|
||||
* @param message message to supply
|
||||
* @param level where to supply line info from in call stack
|
||||
*/
|
||||
@@ -86,7 +93,11 @@ public class LuaError extends RuntimeException {
|
||||
this.traceback = DebugLib.traceback(1);
|
||||
}
|
||||
|
||||
/** Add file and line info to a message at a particular level */
|
||||
/**
|
||||
* Add file and line info to a message at a particular level
|
||||
* @param message the String message to use
|
||||
* @param level where to supply line info from in call stack
|
||||
* */
|
||||
private static String addFileLine( String message, int level ) {
|
||||
if ( message == null ) return null;
|
||||
if ( level == 0 ) return message;
|
||||
@@ -94,19 +105,15 @@ public class LuaError extends RuntimeException {
|
||||
return fileline!=null? fileline+": "+message: message;
|
||||
}
|
||||
|
||||
/** Add file and line info for the nearest enclosing closure */
|
||||
/** Add file and line info for the nearest enclosing closure
|
||||
* @param message the String message to use
|
||||
* */
|
||||
private static String addFileLine( String message ) {
|
||||
if ( message == null ) return null;
|
||||
String fileline = DebugLib.fileline();
|
||||
return fileline!=null? fileline+": "+message: message;
|
||||
}
|
||||
|
||||
// /** Get the message, including source line info if there is any */
|
||||
// public String getMessage() {
|
||||
// String msg = super.getMessage();
|
||||
// return msg!=null && traceback!=null? traceback+": "+msg: msg;
|
||||
// }
|
||||
|
||||
/** Print the message and stack trace */
|
||||
public void printStackTrace() {
|
||||
System.out.println( toString() );
|
||||
|
||||
@@ -21,6 +21,21 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
/**
|
||||
* Class to encapsulate behavior of the singleton instance {@code nil}
|
||||
* <p>
|
||||
* There will be one instance of this class, {@link LuaValue#NIL},
|
||||
* per Java virtual machine.
|
||||
* However, the {@link Varargs} instance {@link LuaValue#NONE}
|
||||
* which is the empty list,
|
||||
* is also considered treated as a nil value by default.
|
||||
* <p>
|
||||
* Although it is possible to test for nil using Java == operator,
|
||||
* the recommended approach is to use the method {@link LuaValue#isnil()}
|
||||
* instead. By using that any ambiguities between
|
||||
* {@link LuaValue#NIL} and {@link LuaValue#NONE} are avoided.
|
||||
*
|
||||
*/
|
||||
public class LuaNil extends LuaValue {
|
||||
|
||||
static final LuaNil _NIL = new LuaNil();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
* Copyright (c) 2009-2011 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
|
||||
@@ -21,6 +21,7 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -31,12 +32,44 @@ import java.util.Hashtable;
|
||||
import org.luaj.vm2.lib.MathLib;
|
||||
import org.luaj.vm2.lib.StringLib;
|
||||
|
||||
/**
|
||||
* Subclass of {@link LuaValue} for representing lua strings.
|
||||
* <p>
|
||||
* Because lua string values are more nearly sequences of bytes than
|
||||
* sequences of characters or unicode code points, the {@link LuaString}
|
||||
* implementation holds the string value in an internal byte array.
|
||||
* <p>
|
||||
* {@link LuaString} values are generally not mutable once constructed,
|
||||
* so multiple {@link LuaString} values can chare a single byte array.
|
||||
* <p>
|
||||
* Currently {@link LuaString}s are pooled via a centrally managed weak table.
|
||||
* To ensure that as many string values as possible take advantage of this,
|
||||
* Constructors are not exposed directly. As with number, booleans, and nil,
|
||||
* instance construction should be via {@link LuaValue#valueOf(byte[])} or similar API.
|
||||
* <p>
|
||||
* When Java Strings are used to initialize {@link LuaString} data, the UTF8 encoding is assumed.
|
||||
* The functions
|
||||
* {@link LuaString#lengthAsUtf8(char[]),
|
||||
* {@link LuaString#encodeToUtf8(char[], byte[], int)}, and
|
||||
* {@link LuaString#decodeAsUtf8(byte[], int, int)
|
||||
* are used to convert back and forth between UTF8 byte arrays and character arrays.
|
||||
*
|
||||
* @see LuaValue
|
||||
* @see LuaValue#valueOf(String)
|
||||
* @see LuaValue#valueOf(byte[])
|
||||
*/
|
||||
public class LuaString extends LuaValue {
|
||||
|
||||
/** The singleton instance representing lua {@code true} */
|
||||
public static LuaValue s_metatable;
|
||||
|
||||
/** The bytes for the string */
|
||||
public final byte[] m_bytes;
|
||||
|
||||
/** The offset into the byte array, 0 means start at the first byte */
|
||||
public final int m_offset;
|
||||
|
||||
/** The number of bytes that comprise this string */
|
||||
public final int m_length;
|
||||
|
||||
private static final Hashtable index_java = new Hashtable();
|
||||
@@ -49,7 +82,13 @@ public class LuaString extends LuaValue {
|
||||
private final static void index_set(Hashtable indextable, Object key, LuaString value) {
|
||||
indextable.put(key, new WeakReference(value));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a {@link LuaString} instance whose bytes match
|
||||
* the supplied Java String using the UTF8 encoding.
|
||||
* @param string Java String containing characters to encode as UTF8
|
||||
* @return {@link LuaString} with UTF8 bytes corresponding to the supplied String
|
||||
*/
|
||||
public static LuaString valueOf(String string) {
|
||||
LuaString s = index_get( index_java, string );
|
||||
if ( s != null ) return s;
|
||||
@@ -60,11 +99,29 @@ public class LuaString extends LuaValue {
|
||||
index_set( index_java, string, s );
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// TODO: should this be deprecated or made private?
|
||||
/** Construct a {@link LuaString} around a byte array without copying the contents.
|
||||
* <p>
|
||||
* The array is used directly after this is called, so clients must not change contents.
|
||||
* <p>
|
||||
* @param bytes byte buffer
|
||||
* @param off offset into the byte buffer
|
||||
* @param len length of the byte buffer
|
||||
* @return {@link LuaString} wrapping the byte buffer
|
||||
*/
|
||||
public static LuaString valueOf(byte[] bytes, int off, int len) {
|
||||
return new LuaString(bytes, off, len);
|
||||
}
|
||||
|
||||
/** Construct a {@link LuaString} using the supplied characters as byte values.
|
||||
* <p>
|
||||
* Only th elow-order 8-bits of each character are used, the remainder is ignored.
|
||||
* <p>
|
||||
* This is most useful for constructing byte sequences that do not conform to UTF8.
|
||||
* @param bytes array of char, whose values are truncated at 8-bits each and put into a byte array.
|
||||
* @return {@link LuaString} wrapping a copy of the byte buffer
|
||||
*/
|
||||
public static LuaString valueOf(char[] bytes) {
|
||||
int n = bytes.length;
|
||||
byte[] b = new byte[n];
|
||||
@@ -73,10 +130,27 @@ public class LuaString extends LuaValue {
|
||||
return valueOf(b, 0, n);
|
||||
}
|
||||
|
||||
|
||||
/** Construct a {@link LuaString} around a byte array without copying the contents.
|
||||
* <p>
|
||||
* The array is used directly after this is called, so clients must not change contents.
|
||||
* <p>
|
||||
* @param bytes byte buffer
|
||||
* @return {@link LuaString} wrapping the byte buffer
|
||||
*/
|
||||
public static LuaString valueOf(byte[] bytes) {
|
||||
return valueOf(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
/** Construct a {@link LuaString} around a byte array without copying the contents.
|
||||
* <p>
|
||||
* The array is used directly after this is called, so clients must not change contents.
|
||||
* <p>
|
||||
* @param bytes byte buffer
|
||||
* @param offset offset into the byte buffer
|
||||
* @param length length of the byte buffer
|
||||
* @return {@link LuaString} wrapping the byte buffer
|
||||
*/
|
||||
private LuaString(byte[] bytes, int offset, int length) {
|
||||
this.m_bytes = bytes;
|
||||
this.m_offset = offset;
|
||||
@@ -364,18 +438,29 @@ public class LuaString extends LuaValue {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Convert value to an input stream.
|
||||
*
|
||||
* @return {@link InputStream} whose data matches the bytes in this {@link LuaString}
|
||||
*/
|
||||
public InputStream toInputStream() {
|
||||
return new ByteArrayInputStream(m_bytes, m_offset, m_length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the bytes of the string into the given byte array.
|
||||
* Copy the bytes of the string into the given byte array.
|
||||
* @param strOffset offset from which to copy
|
||||
* @param bytes destination byte array
|
||||
* @param arrayOffset offset in destination
|
||||
* @param len number of bytes to copy
|
||||
*/
|
||||
public void copyInto( int strOffset, byte[] bytes, int arrayOffset, int len ) {
|
||||
System.arraycopy( m_bytes, m_offset+strOffset, bytes, arrayOffset, len );
|
||||
}
|
||||
|
||||
/** Java version of strpbrk, which is a terribly named C function. */
|
||||
/** Java version of strpbrk - find index of any byte that in an accept string.
|
||||
* @param accept {@link LuaString} containing characters to look for.
|
||||
* @return index of first match in the {@code accept} string, or -1 if not found.
|
||||
*/
|
||||
public int indexOfAny( LuaString accept ) {
|
||||
final int ilimit = m_offset + m_length;
|
||||
final int jlimit = accept.m_offset + accept.m_length;
|
||||
@@ -389,6 +474,12 @@ public class LuaString extends LuaValue {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index of a byte starting at a point in this string
|
||||
* @param b the byte to look for
|
||||
* @param start the first index in the string
|
||||
* @return index of first match found, or -1 if not found.
|
||||
*/
|
||||
public int indexOf( byte b, int start ) {
|
||||
for ( int i=0, j=m_offset+start; i < m_length; ++i ) {
|
||||
if ( m_bytes[j++] == b )
|
||||
@@ -397,6 +488,12 @@ public class LuaString extends LuaValue {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index of a string starting at a point in this string
|
||||
* @param s the string to search for
|
||||
* @param start the first index in the string
|
||||
* @return index of first match found, or -1 if not found.
|
||||
*/
|
||||
public int indexOf( LuaString s, int start ) {
|
||||
final int slen = s.length();
|
||||
final int limit = m_offset + m_length - slen;
|
||||
@@ -408,6 +505,11 @@ public class LuaString extends LuaValue {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the last index of a string in this string
|
||||
* @param s the string to search for
|
||||
* @return index of last match found, or -1 if not found.
|
||||
*/
|
||||
public int lastIndexOf( LuaString s ) {
|
||||
final int slen = s.length();
|
||||
final int limit = m_offset + m_length - slen;
|
||||
@@ -419,10 +521,17 @@ public class LuaString extends LuaValue {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// --------------------- utf8 conversion -------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Convert to Java String interpreting as utf8 characters
|
||||
* Convert to Java String interpreting as utf8 characters.
|
||||
*
|
||||
* @param bytes byte array in UTF8 encoding to convert
|
||||
* @param offset starting index in byte array
|
||||
* @param length number of bytes to convert
|
||||
* @return Java String corresponding to the value of bytes interpreted using UTF8
|
||||
* @see #lengthAsUtf8(char[])
|
||||
* @see #encodeToUtf8(char[], byte[], int)
|
||||
* @see #isValidUtf8()
|
||||
*/
|
||||
public static String decodeAsUtf8(byte[] bytes, int offset, int length) {
|
||||
int i,j,n,b;
|
||||
@@ -444,6 +553,11 @@ public class LuaString extends LuaValue {
|
||||
|
||||
/**
|
||||
* Count the number of bytes required to encode the string as UTF-8.
|
||||
* @param chars Array of unicode characters to be encoded as UTF-8
|
||||
* @return count of bytes needed to encode using UTF-8
|
||||
* @see #encodeToUtf8(char[], byte[], int)
|
||||
* @see #decodeAsUtf8(byte[], int, int)
|
||||
* @see #isValidUtf8()
|
||||
*/
|
||||
public static int lengthAsUtf8(char[] chars) {
|
||||
int i,b;
|
||||
@@ -456,8 +570,16 @@ public class LuaString extends LuaValue {
|
||||
|
||||
/**
|
||||
* Encode the given Java string as UTF-8 bytes, writing the result to bytes
|
||||
* starting at offset. The string should be measured first with lengthAsUtf8
|
||||
* starting at offset.
|
||||
* <p>
|
||||
* The string should be measured first with lengthAsUtf8
|
||||
* to make sure the given byte array is large enough.
|
||||
* @param chars Array of unicode characters to be encoded as UTF-8
|
||||
* @param bytes byte array to hold the result
|
||||
* @param off offset into the byte array to start writing
|
||||
* @see #lengthAsUtf8(char[])
|
||||
* @see #decodeAsUtf8(byte[], int, int)
|
||||
* @see #isValidUtf8()
|
||||
*/
|
||||
public static void encodeToUtf8(char[] chars, byte[] bytes, int off) {
|
||||
final int n = chars.length;
|
||||
@@ -476,6 +598,12 @@ public class LuaString extends LuaValue {
|
||||
}
|
||||
}
|
||||
|
||||
/** Check that a byte sequence is valid UTF-8
|
||||
* @return true if it is valid UTF-8, otherwise false
|
||||
* @see #lengthAsUtf8(char[])
|
||||
* @see #encodeToUtf8(char[], byte[], int)
|
||||
* @see #decodeAsUtf8(byte[], int, int)
|
||||
*/
|
||||
public boolean isValidUtf8() {
|
||||
int i,j,n,b,e=0;
|
||||
for ( i=m_offset,j=m_offset+m_length,n=0; i<j; ++n ) {
|
||||
@@ -497,7 +625,9 @@ public class LuaString extends LuaValue {
|
||||
|
||||
/**
|
||||
* convert to a number using a supplied base, or NIL if it can't be converted
|
||||
* @return IntValue, DoubleValue, or NIL depending on the content of the string.
|
||||
* @param base the base to use, such as 10
|
||||
* @return IntValue, DoubleValue, or NIL depending on the content of the string.
|
||||
* @see LuaValue#tonumber()
|
||||
*/
|
||||
public LuaValue tonumber( int base ) {
|
||||
double d = scannumber( base );
|
||||
@@ -506,6 +636,8 @@ public class LuaString extends LuaValue {
|
||||
|
||||
/**
|
||||
* Convert to a number in a base, or return Double.NaN if not a number.
|
||||
* @param base the base to use, such as 10
|
||||
* @return double value if conversion is valid, or Double.NaN if not
|
||||
*/
|
||||
public double scannumber( int base ) {
|
||||
if ( base >= 2 && base <= 36 ) {
|
||||
@@ -527,7 +659,11 @@ public class LuaString extends LuaValue {
|
||||
|
||||
/**
|
||||
* Scan and convert a long value, or return Double.NaN if not found.
|
||||
* @return DoubleValue, IntValue, or Double.NaN depending on what is found.
|
||||
* @param base the base to use, such as 10
|
||||
* @param start the index to start searching from
|
||||
* @param end the first index beyond the search range
|
||||
* @return double value if conversion is valid,
|
||||
* or Double.NaN if not
|
||||
*/
|
||||
private double scanlong( int base, int start, int end ) {
|
||||
long x = 0;
|
||||
@@ -544,7 +680,10 @@ public class LuaString extends LuaValue {
|
||||
|
||||
/**
|
||||
* Scan and convert a double value, or return Double.NaN if not a double.
|
||||
* @return DoubleValue, IntValue, or Double.NaN depending on what is found.
|
||||
* @param start the index to start searching from
|
||||
* @param end the first index beyond the search range
|
||||
* @return double value if conversion is valid,
|
||||
* or Double.NaN if not
|
||||
*/
|
||||
private double scandouble(int start, int end) {
|
||||
if ( end>start+64 ) end=start+64;
|
||||
|
||||
@@ -23,26 +23,90 @@ package org.luaj.vm2;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Subclass of {@link LuaValue} for representing lua tables.
|
||||
* <p>
|
||||
* Almost all API's implemented in {@link LuaTable} are defined and documented in {@link LuaValue}.
|
||||
* <p>
|
||||
* If a table is needed, the one of the type-checking functions can be used such as
|
||||
* {@link #istable()},
|
||||
* {@link #checktable()}, or
|
||||
* {@link #opttable(LuaTable)}
|
||||
* <p>
|
||||
* The main table operations are defined on {@link LuaValue}
|
||||
* for getting and setting values with and without metatag processing:
|
||||
* <ul>
|
||||
* <li>{@link #get(LuaValue)}</li>
|
||||
* <li>{@link #set(LuaValue,LuaValue)}</li>
|
||||
* <li>{@link #rawget(LuaValue)}</li>
|
||||
* <li>{@link #rawset(LuaValue,LuaValue)}</li>
|
||||
* <li>plus overloads such as {@link #get(String)}, {@link #get(int)}, and so on</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* To iterate over key-value pairs from Java, use
|
||||
* <pre> {@code
|
||||
* LuaValue k = LuaValue.NIL;
|
||||
* while ( true ) {
|
||||
* Varargs n = table.next(k);
|
||||
* if ( (k = n.arg1()).isnil() )
|
||||
* break;
|
||||
* LuaValue v = n.arg(2)
|
||||
* process( k, v )
|
||||
* }</pre>
|
||||
*
|
||||
* <p>
|
||||
* As with other types, {@link LuaTable} instances should be constructed via one of the table constructor
|
||||
* methods on {@link LuaValue}:
|
||||
* <ul>
|
||||
* <li>{@link LuaValue#tableOf()} empty table</li>
|
||||
* <li>{@link LuaValue#tableOf(int, int)} table with capacity</li>
|
||||
* <li>{@link LuaValue#tableOf(LuaValue[])} initialize array part</li>
|
||||
* <li>{@link LuaValue#tableOf(Varargs, int)} initialize array part</li>
|
||||
* <li>{@link LuaValue#tableOf(LuaValue[], LuaValue[])} initialize array and named parts</li>
|
||||
* <li>{@link LuaValue#tableOf(LuaValue[], LuaValue[], Varargs)} initialize array and named parts</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class LuaTable extends LuaValue {
|
||||
private static final int MIN_HASH_CAPACITY = 2;
|
||||
private static final LuaString N = valueOf("n");
|
||||
|
||||
/** the array values */
|
||||
protected LuaValue[] array;
|
||||
|
||||
/** the hash keys */
|
||||
protected LuaValue[] hashKeys;
|
||||
|
||||
/** the hash values */
|
||||
protected LuaValue[] hashValues;
|
||||
|
||||
/** the number of hash entries */
|
||||
protected int hashEntries;
|
||||
|
||||
/** metatable for this table, or null */
|
||||
protected LuaValue m_metatable;
|
||||
|
||||
/** Construct empty table */
|
||||
public LuaTable() {
|
||||
array = NOVALS;
|
||||
hashKeys = NOVALS;
|
||||
hashValues = NOVALS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct table with preset capacity.
|
||||
* @param narray capacity of array part
|
||||
* @param nhash capacity of hash part
|
||||
*/
|
||||
public LuaTable(int narray, int nhash) {
|
||||
presize(narray, nhash);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct table with named and unnamed parts.
|
||||
* @param named Named elements in order {@code key-a, value-a, key-b, value-b, ... }
|
||||
* @param unnamed Unnamed elements in order {@code value-1, value-2, ... }
|
||||
* @param lastarg Additional unnamed values beyond {@code unnamed.length}
|
||||
*/
|
||||
public LuaTable(LuaValue[] named, LuaValue[] unnamed, Varargs lastarg) {
|
||||
int nn = (named!=null? named.length: 0);
|
||||
int nu = (unnamed!=null? unnamed.length: 0);
|
||||
@@ -58,10 +122,19 @@ public class LuaTable extends LuaValue {
|
||||
rawset(named[i], named[i+1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct table of unnamed elements.
|
||||
* @param varargs Unnamed elements in order {@code value-1, value-2, ... }
|
||||
*/
|
||||
public LuaTable(Varargs varargs) {
|
||||
this(varargs,1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct table of unnamed elements.
|
||||
* @param varargs Unnamed elements in order {@code value-1, value-2, ... }
|
||||
* @param firstarg the index in varargs of the first argument to include in the table
|
||||
*/
|
||||
public LuaTable(Varargs varargs, int firstarg) {
|
||||
int nskip = firstarg-1;
|
||||
int n = Math.max(varargs.narg()-nskip,0);
|
||||
@@ -105,16 +178,25 @@ public class LuaTable extends LuaValue {
|
||||
hashEntries = 0;
|
||||
}
|
||||
|
||||
/** Resize the table */
|
||||
private static LuaValue[] resize( LuaValue[] old, int n ) {
|
||||
LuaValue[] v = new LuaValue[n];
|
||||
System.arraycopy(old, 0, v, 0, old.length);
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of the array part of the table.
|
||||
* @return length of the array part, does not relate to count of objects in the table.
|
||||
*/
|
||||
protected int getArrayLength() {
|
||||
return array.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of the hash part of the table.
|
||||
* @return length of the hash part, does not relate to count of objects in the table.
|
||||
*/
|
||||
protected int getHashLength() {
|
||||
return hashValues.length;
|
||||
}
|
||||
@@ -135,6 +217,12 @@ public class LuaTable extends LuaValue {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the mode of a table
|
||||
* @param weakkeys true to make the table have weak keys going forward
|
||||
* @param weakvalues true to make the table have weak values going forward
|
||||
* @return {@code this} or a new {@link WeakTable} if the mode change requires copying.
|
||||
*/
|
||||
protected LuaTable changemode(boolean weakkeys, boolean weakvalues) {
|
||||
if ( weakkeys || weakvalues )
|
||||
return new WeakTable(weakkeys, weakvalues, this);
|
||||
@@ -197,6 +285,7 @@ public class LuaTable extends LuaValue {
|
||||
hashset( key, value );
|
||||
}
|
||||
|
||||
/** Set an array element */
|
||||
private boolean arrayset( int key, LuaValue value ) {
|
||||
if ( key>0 && key<=array.length ) {
|
||||
array[key-1] = (value.isnil()? null: value);
|
||||
@@ -208,7 +297,8 @@ public class LuaTable extends LuaValue {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Expand the array part */
|
||||
private void expandarray() {
|
||||
int n = array.length;
|
||||
int m = Math.max(2,n*2);
|
||||
@@ -223,6 +313,11 @@ public class LuaTable extends LuaValue {
|
||||
}
|
||||
}
|
||||
|
||||
/** Remove the element at a position in a list-table
|
||||
*
|
||||
* @param pos the position to remove
|
||||
* @return The removed item, or {@link #NONE} if not removed
|
||||
*/
|
||||
public LuaValue remove(int pos) {
|
||||
if ( pos == 0 )
|
||||
pos = length();
|
||||
@@ -234,6 +329,11 @@ public class LuaTable extends LuaValue {
|
||||
return v.isnil()? NONE: v;
|
||||
}
|
||||
|
||||
/** Insert an element at a position in a list-table
|
||||
*
|
||||
* @param pos the position to remove
|
||||
* @param value The value to insert
|
||||
*/
|
||||
public void insert(int pos, LuaValue value) {
|
||||
if ( pos == 0 )
|
||||
pos = length()+1;
|
||||
@@ -244,6 +344,13 @@ public class LuaTable extends LuaValue {
|
||||
}
|
||||
}
|
||||
|
||||
/** Concatenate the contents of a table efficiently, using {@link Buffer}
|
||||
*
|
||||
* @param sep {@link LuaString} separater to apply between elements
|
||||
* @param i the first element index
|
||||
* @param j the last element index, inclusive
|
||||
* @return {@link LuaString} value of the concatenation
|
||||
*/
|
||||
public LuaValue concat(LuaString sep, int i, int j) {
|
||||
Buffer sb = new Buffer ();
|
||||
if ( i<=j ) {
|
||||
@@ -263,9 +370,6 @@ public class LuaTable extends LuaValue {
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of this table, as lua defines it.
|
||||
*/
|
||||
public int length() {
|
||||
int a = getArrayLength();
|
||||
int n = a+1,m=0;
|
||||
@@ -287,6 +391,11 @@ public class LuaTable extends LuaValue {
|
||||
return LuaInteger.valueOf(length());
|
||||
}
|
||||
|
||||
/** Return table.maxn() as defined by lua 5.0.
|
||||
* <p>
|
||||
* Provided for compatibility, not a scalable operation.
|
||||
* @return value for maxn
|
||||
*/
|
||||
public int maxn() {
|
||||
int n = 0;
|
||||
for ( int i=0; i<array.length; i++ )
|
||||
@@ -303,10 +412,6 @@ public class LuaTable extends LuaValue {
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next element after a particular key in the table
|
||||
* @return key,value or nil
|
||||
*/
|
||||
/**
|
||||
* Get the next element after a particular key in the table
|
||||
* @return key,value or nil
|
||||
@@ -388,8 +493,11 @@ public class LuaTable extends LuaValue {
|
||||
}
|
||||
|
||||
|
||||
// ======================= hashset =================
|
||||
|
||||
/**
|
||||
* Set a hashtable value
|
||||
* @param key key to set
|
||||
* @param value value to set
|
||||
*/
|
||||
public void hashset(LuaValue key, LuaValue value) {
|
||||
if ( value.isnil() )
|
||||
hashRemove(key);
|
||||
@@ -408,6 +516,11 @@ public class LuaTable extends LuaValue {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the hashtable slot to use
|
||||
* @param key key to look for
|
||||
* @return slot to use
|
||||
*/
|
||||
public int hashFindSlot(LuaValue key) {
|
||||
int i = ( key.hashCode() & 0x7FFFFFFF ) % hashKeys.length;
|
||||
|
||||
@@ -437,6 +550,10 @@ public class LuaTable extends LuaValue {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear a particular slot in the table
|
||||
* @param i slot to clear.
|
||||
*/
|
||||
protected void hashClearSlot( int i ) {
|
||||
if ( hashKeys[ i ] != null ) {
|
||||
|
||||
@@ -497,6 +614,9 @@ public class LuaTable extends LuaValue {
|
||||
//
|
||||
// Only sorts the contiguous array part.
|
||||
//
|
||||
/** Sort the table using a comparator.
|
||||
* @param comparator {@link LuaValue} to be called to compare elements.
|
||||
*/
|
||||
public void sort(LuaValue comparator) {
|
||||
int n = array.length;
|
||||
while ( n > 0 && array[n-1] == null )
|
||||
@@ -550,7 +670,9 @@ public class LuaTable extends LuaValue {
|
||||
}
|
||||
|
||||
/** This may be deprecated in a future release.
|
||||
* It is recommended to count via iteration over next() instead */
|
||||
* It is recommended to count via iteration over next() instead
|
||||
* @return count of keys in the table
|
||||
* */
|
||||
public int keyCount() {
|
||||
LuaValue k = LuaValue.NIL;
|
||||
for ( int i=0; true; i++ ) {
|
||||
@@ -561,7 +683,9 @@ public class LuaTable extends LuaValue {
|
||||
}
|
||||
|
||||
/** This may be deprecated in a future release.
|
||||
* It is recommended to use next() instead */
|
||||
* It is recommended to use next() instead
|
||||
* @return array of keys in the table
|
||||
* */
|
||||
public LuaValue[] keys() {
|
||||
Vector l = new Vector();
|
||||
LuaValue k = LuaValue.NIL;
|
||||
|
||||
@@ -24,6 +24,11 @@ package org.luaj.vm2;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
* Debug helper class to pretty-print lua bytecodes.
|
||||
* @see Prototype
|
||||
* @see LuaClosure
|
||||
*/
|
||||
public class Print extends Lua {
|
||||
|
||||
/** opcode names */
|
||||
@@ -131,6 +136,10 @@ public class Print extends Lua {
|
||||
printValue( ps, f.k[i] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the code in a prototype
|
||||
* @param f the {@link Prototype}
|
||||
*/
|
||||
public static void printCode(Prototype f) {
|
||||
int[] code = f.code;
|
||||
int pc, n = code.length;
|
||||
@@ -140,10 +149,21 @@ public class Print extends Lua {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an opcode in a prototype
|
||||
* @param f the {@link Prototype}
|
||||
* @param pc the program counter to look up and print
|
||||
*/
|
||||
public static void printOpCode(Prototype f, int pc) {
|
||||
printOpCode(ps,f,pc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an opcode in a prototype
|
||||
* @param ps the {@link PrintStream} to print to
|
||||
* @param f the {@link Prototype}
|
||||
* @param pc the program counter to look up and print
|
||||
*/
|
||||
public static void printOpCode(PrintStream ps, Prototype f, int pc) {
|
||||
int[] code = f.code;
|
||||
int i = code[pc];
|
||||
@@ -334,7 +354,15 @@ public class Print extends Lua {
|
||||
if ( !b )
|
||||
throw new NullPointerException("_assert failed");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print the state of a {@link LuaClosure} that is being executed
|
||||
* @param cl the {@link LuaClosure}
|
||||
* @param pc the program counter
|
||||
* @param stack the stack of {@link LuaValue}
|
||||
* @param top the top of the stack
|
||||
* @param varargs any {@link Varargs} value that may apply
|
||||
*/
|
||||
public static void printState(LuaClosure cl, int pc, LuaValue[] stack, int top, Varargs varargs) {
|
||||
// print opcode into buffer
|
||||
PrintStream previous = ps;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
* Copyright (c) 2009-2011 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
|
||||
@@ -21,7 +21,16 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
|
||||
/**
|
||||
* Prototype representing compiled lua code.
|
||||
* <p>
|
||||
* This is both a straight translation of the corresponding C type,
|
||||
* and the main data structure for execution of compiled lua bytecode.
|
||||
* <p>
|
||||
* See documentatation on {@link LuaClosure} for information on how to load
|
||||
* and execute a {@link Prototype}.
|
||||
* @see LuaClosure
|
||||
*/
|
||||
|
||||
public class Prototype {
|
||||
/* constants used by the function */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Luaj.org. All rights reserved.
|
||||
* Copyright (c) 2010-2011 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
|
||||
@@ -21,6 +21,25 @@
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
/**
|
||||
* Subclass of {@link Varargs} that represents a lua tail call
|
||||
* in a Java library function execution environment.
|
||||
* <p>
|
||||
* Since Java doesn't have direct support for tail calls,
|
||||
* any lua function whose {@link Prototype} contains the
|
||||
* {@link Lua#OP_TAILCALL} bytecode needs a mechanism
|
||||
* for tail calls when converting lua-bytecode to java-bytecode.
|
||||
* <p>
|
||||
* The tail call holds the next function and arguments,
|
||||
* and the client a call to {@link #eval()} executes the function
|
||||
* repeatedly until the tail calls are completed.
|
||||
* <p>
|
||||
* Normally, users of luaj need not concern themselves with the
|
||||
* details of this mechanism, as it is built into the core
|
||||
* execution framework.
|
||||
* @see Prototype
|
||||
* @see LuaJC
|
||||
*/
|
||||
public class TailcallVarargs extends Varargs {
|
||||
|
||||
private LuaValue func;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
* Copyright (c) 2009-2011 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
|
||||
@@ -22,29 +22,54 @@
|
||||
package org.luaj.vm2;
|
||||
|
||||
|
||||
/** Upvalue used with Closure formulation */
|
||||
/** Upvalue used with Closure formulation
|
||||
* <p>
|
||||
* @see LuaClosure
|
||||
* @see Prototype
|
||||
*/
|
||||
public final class UpValue {
|
||||
|
||||
LuaValue[] array; // initially the stack, becomes a holder
|
||||
int index;
|
||||
|
||||
|
||||
/**
|
||||
* Create an upvalue relative to a stack
|
||||
* @param stack the stack
|
||||
* @param index the index on the stack for the upvalue
|
||||
*/
|
||||
public UpValue( LuaValue[] stack, int index) {
|
||||
this.array = stack;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this upvalue to a Java String
|
||||
* @return the Java String for this upvalue.
|
||||
* @see LuaValue#tojstring()
|
||||
*/
|
||||
public String tojstring() {
|
||||
return array[index].tojstring();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the upvalue
|
||||
* @return the {@link LuaValue} for this upvalue
|
||||
*/
|
||||
public final LuaValue getValue() {
|
||||
return array[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the upvalue
|
||||
* @param the {@link LuaValue} to set it to
|
||||
*/
|
||||
public final void setValue( LuaValue value ) {
|
||||
array[index] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close this upvalue so it is no longer on the stack
|
||||
*/
|
||||
public final void close() {
|
||||
array = new LuaValue[] { array[index] };
|
||||
index = 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
* Copyright (c) 2009-2011 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
|
||||
@@ -25,17 +25,46 @@ import java.lang.ref.WeakReference;
|
||||
|
||||
import org.luaj.vm2.lib.TwoArgFunction;
|
||||
|
||||
/**
|
||||
* Subclass of {@link LuaTable} that provides weak key and weak value semantics.
|
||||
* <p>
|
||||
* Normally these are not created directly, but indirectly when changing the mode
|
||||
* of a {@link LuaTable} as lua script executes.
|
||||
* <p>
|
||||
* However, calling the constructors directly when weak tables are required from
|
||||
* Java will reduce overhead.
|
||||
*/
|
||||
public class WeakTable extends LuaTable {
|
||||
private boolean weakkeys,weakvalues;
|
||||
|
||||
/**
|
||||
* Construct a table with weak keys, weak values, or both
|
||||
* @param weakkeys true to let the table have weak keys
|
||||
* @param weakvalues true to let the table have weak values
|
||||
*/
|
||||
public WeakTable(boolean weakkeys, boolean weakvalues) {
|
||||
this(weakkeys, weakvalues, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a table with weak keys, weak values, or both, and an initial capacity
|
||||
* @param weakkeys true to let the table have weak keys
|
||||
* @param weakvalues true to let the table have weak values
|
||||
* @param narray capacity of array part
|
||||
* @param nhash capacity of hash part
|
||||
*/
|
||||
protected WeakTable(boolean weakkeys, boolean weakvalues, int narray, int nhash) {
|
||||
super(narray, nhash);
|
||||
this.weakkeys = weakkeys;
|
||||
this.weakvalues = weakvalues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a table with weak keys, weak values, or both, and a source of initial data
|
||||
* @param weakkeys true to let the table have weak keys
|
||||
* @param weakvalues true to let the table have weak values
|
||||
* @param source {@link LuaTable} containing the initial elements
|
||||
*/
|
||||
protected WeakTable(boolean weakkeys, boolean weakvalues, LuaTable source) {
|
||||
this(weakkeys, weakvalues, source.getArrayLength(), source.getHashLength());
|
||||
Varargs n;
|
||||
@@ -49,6 +78,11 @@ public class WeakTable extends LuaTable {
|
||||
super.presize(narray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Presize capacity of both array and hash parts.
|
||||
* @param narray capacity of array part
|
||||
* @param nhash capacity of hash part
|
||||
*/
|
||||
public void presize(int narray, int nhash) {
|
||||
super.presize(narray, nhash);
|
||||
}
|
||||
@@ -67,6 +101,11 @@ public class WeakTable extends LuaTable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Self-sent message to convert a value to its weak counterpart
|
||||
* @param value value to convert
|
||||
* @return {@link LuaValue} that is a strong or weak reference, depending on type of {@code value}
|
||||
*/
|
||||
LuaValue weaken( LuaValue value ) {
|
||||
switch ( value.type() ) {
|
||||
case LuaValue.TFUNCTION:
|
||||
@@ -85,8 +124,7 @@ public class WeakTable extends LuaTable {
|
||||
value = weaken( value );
|
||||
super.rawset(key, value);
|
||||
}
|
||||
|
||||
/** caller must ensure key is not nil */
|
||||
|
||||
public void rawset( LuaValue key, LuaValue value ) {
|
||||
if ( weakvalues )
|
||||
value = weaken( value );
|
||||
@@ -114,6 +152,9 @@ public class WeakTable extends LuaTable {
|
||||
return super.rawget(key).strongvalue();
|
||||
}
|
||||
|
||||
/** Get the hash value for a key
|
||||
* key the key to look up
|
||||
* */
|
||||
protected LuaValue hashget(LuaValue key) {
|
||||
if ( hashEntries > 0 ) {
|
||||
int i = hashFindSlot(key);
|
||||
@@ -179,6 +220,9 @@ public class WeakTable extends LuaTable {
|
||||
} );
|
||||
}
|
||||
|
||||
/** Internal class to implement weak values.
|
||||
* @see WeakTable
|
||||
*/
|
||||
static class WeakValue extends LuaValue {
|
||||
final WeakReference ref;
|
||||
|
||||
@@ -215,6 +259,9 @@ public class WeakTable extends LuaTable {
|
||||
}
|
||||
}
|
||||
|
||||
/** Internal class to implement weak userdata values.
|
||||
* @see WeakTable
|
||||
*/
|
||||
static final class WeakUserdata extends WeakValue {
|
||||
private final WeakReference ob;
|
||||
private final LuaValue mt;
|
||||
@@ -247,6 +294,9 @@ public class WeakTable extends LuaTable {
|
||||
}
|
||||
}
|
||||
|
||||
/** Internal class to implement weak table entries.
|
||||
* @see WeakTable
|
||||
*/
|
||||
static final class WeakEntry extends LuaValue {
|
||||
final LuaValue weakkey;
|
||||
LuaValue weakvalue;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
||||
* Copyright (c) 2009-2011 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
|
||||
@@ -38,7 +38,19 @@ import org.luaj.vm2.LoadState.LuaCompiler;
|
||||
|
||||
|
||||
/**
|
||||
* Compiler for Lua
|
||||
* Compiler for Lua.
|
||||
* <p>
|
||||
* Compiles lua source files into lua bytecode within a {@link Prototype},
|
||||
* loads lua binary files directly into a{@link Prototype},
|
||||
* and optionaly instantiates a {@link LuaClosure} around the result
|
||||
* using a user-supplied environment.
|
||||
* <p>
|
||||
* Implements the {@link LuaCompiler} interface for loading
|
||||
* initialized chunks, which is an interface common to
|
||||
* lua bytecode compiling and java bytecode compiling.
|
||||
* <p>
|
||||
* @see LuaCompiler
|
||||
* @see Prototype
|
||||
*/
|
||||
public class LuaC extends Lua implements LuaCompiler {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user