diff --git a/.gitignore b/.gitignore index d7642856..df07b267 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ bin/ target/ build/ -lib/ jit/ *.ser *.gz diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..d74b1d54 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2007 LuaJ. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index d0ca2241..30f17dbd 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ James Roseborough, Ian Farmer, Version 3.0.2 Copyright © 2009-2014 Luaj.org. Freely available under the terms of the -Luaj license. +Luaj license.

@@ -412,7 +412,7 @@ and the math operations include all those supported by Java SE. Android applications should use the JsePlatform, and can include the Luajava library to simplify access to underlying Android APIs. A specialized Globals.finder should be provided to find scripts and data for loading. -See examples/android/src/android/LuajView +See examples/android/src/android/LuajView.java for an example that loads from the "res" Android project directory. The ant build script is examples/android/build.xml. diff --git a/src/core/org/luaj/vm2/LoadState.java b/src/core/org/luaj/vm2/LoadState.java index ece3f885..8d71a74a 100644 --- a/src/core/org/luaj/vm2/LoadState.java +++ b/src/core/org/luaj/vm2/LoadState.java @@ -31,10 +31,10 @@ import java.io.InputStream; *

* The {@link LoadState} class provides the default {@link Globals.Undumper} * which is used to undump a string of bytes that represent a lua binary file -* using either the C-based lua compiler, or luaj's +* using either the C-based lua compiler, or luaj's * {@link org.luaj.vm2.compiler.LuaC} compiler. *

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

 {@code
 * Globals globals = JsePlatform.standardGlobals();
@@ -44,10 +44,10 @@ import java.io.InputStream;
 * This should work regardless of which {@link Globals.Compiler} or {@link Globals.Undumper}
 * have been installed.
 * 

-* By default, when using {@link org.luaj.vm2.lib.jse.JsePlatform} or +* By default, when using {@link org.luaj.vm2.lib.jse.JsePlatform} or * {@link org.luaj.vm2.lib.jme.JmePlatform} * to construct globals, the {@link LoadState} default undumper is installed -* as the default {@link Globals.Undumper}. +* as the default {@link Globals.Undumper}. *

* * A lua binary file is created via the {@link org.luaj.vm2.compiler.DumpState} class @@ -60,7 +60,7 @@ import java.io.InputStream; * byte[] lua_binary_file_bytes = o.toByteArray(); * }

* -* The {@link LoadState}'s default undumper {@link #instance} +* The {@link LoadState}'s default undumper {@link #instance} * may be used directly to undump these bytes: *
 {@code
 * Prototypep = LoadState.instance.undump(new ByteArrayInputStream(lua_binary_file_bytes), "main.lua");
@@ -99,7 +99,7 @@ public class LoadState {
 	/** format corresponding to number-patched lua, all numbers are 32-bit (4 byte) ints */
 	public static final int NUMBER_FORMAT_NUM_PATCH_INT32      = 4;
 	
-	// type constants	
+	// type constants
 	public static final int LUA_TINT            = (-2);
 	public static final int LUA_TNONE			= (-1);
 	public static final int LUA_TNIL			= 0;
@@ -155,7 +155,6 @@ public class LoadState {
 	private static final LuaValue[]     NOVALUES    = {};
 	private static final Prototype[] NOPROTOS    = {};
 	private static final LocVars[]   NOLOCVARS   = {};
-	private static final LuaString[]  NOSTRVALUES = {};
 	private static final Upvaldesc[]  NOUPVALDESCS = {};
 	private static final int[]       NOINTS      = {};
 	
@@ -168,17 +167,17 @@ public class LoadState {
 	}
 	
 	/** Load a 4-byte int value from the input stream
-	 * @return the int value laoded.  
+	 * @return the int value laoded.
 	 **/
 	int loadInt() throws IOException {
 		is.readFully(buf,0,4);
-		return luacLittleEndian? 
+		return luacLittleEndian?
 				(buf[3] << 24) | ((0xff & buf[2]) << 16) | ((0xff & buf[1]) << 8) | (0xff & buf[0]):
 				(buf[0] << 24) | ((0xff & buf[1]) << 16) | ((0xff & buf[2]) << 8) | (0xff & buf[3]);
 	}
 	
 	/** Load an array of int values from the input stream
-	 * @return the array of int values laoded.  
+	 * @return the array of int values laoded.
 	 **/
 	int[] loadIntArray() throws IOException {
 		int n = loadInt();
@@ -192,7 +191,7 @@ public class LoadState {
 		is.readFully(buf,0,m);
 		int[] array = new int[n];
 		for ( int i=0, j=0; i
@@ -415,7 +417,7 @@ public class LuaClosure extends LuaFunction {
 					{
 			            LuaValue limit = stack[a + 1];
 						LuaValue step  = stack[a + 2];
-						LuaValue idx   = step.add(stack[a]);
+						LuaValue idx   = stack[a].add(step);
 			            if (step.gt_b(0)? idx.lteq_b(limit): idx.gteq_b(limit)) {
 		                    stack[a] = idx;
 		                    stack[a + 3] = idx;
@@ -547,8 +549,24 @@ public class LuaClosure extends LuaFunction {
 	}
 
 	private void processErrorHooks(LuaError le, Prototype p, int pc) {
-		le.fileline = (p.source != null? p.source.tojstring(): "?") + ":"
-			+ (p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length? String.valueOf(p.lineinfo[pc]): "?") + ": ";
+		String file = "?";
+		int line = -1;
+		{
+			CallFrame frame = null;
+			if (globals != null && globals.debuglib != null) {
+				frame = globals.debuglib.getCallFrame(le.level);
+				if (frame != null) {
+					String src = frame.shortsource();
+					file = src != null ? src : "?";
+					line = frame.currentline();
+				}
+			}
+			if (frame == null) {
+				file = p.source != null? p.source.tojstring(): "?";
+				line = p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length ? p.lineinfo[pc] : -1;
+			}
+		}
+		le.fileline = file + ": " + line;
 		le.traceback = errorHook(le.getMessage(), le.level);
 	}
 	
diff --git a/src/core/org/luaj/vm2/LuaDouble.java b/src/core/org/luaj/vm2/LuaDouble.java
index 67b05996..c23e7849 100644
--- a/src/core/org/luaj/vm2/LuaDouble.java
+++ b/src/core/org/luaj/vm2/LuaDouble.java
@@ -25,12 +25,12 @@ import org.luaj.vm2.compat.JavaCompat;
 import org.luaj.vm2.lib.MathLib;
 
 /**
- * Extension of {@link LuaNumber} which can hold a Java double as its value. 
+ * Extension of {@link LuaNumber} which can hold a Java double as its value.
  * 

- * These instance are not instantiated directly by clients, but indirectly + * These instance are not instantiated directly by clients, but indirectly * via the static functions {@link LuaValue#valueOf(int)} or {@link LuaValue#valueOf(double)} - * functions. This ensures that values which can be represented as int - * are wrapped in {@link LuaInteger} instead of {@link LuaDouble}. + * functions. This ensures that values which can be represented as int + * are wrapped in {@link LuaInteger} instead of {@link LuaDouble}. *

* Almost all API's implemented in LuaDouble are defined and documented in {@link LuaValue}. *

@@ -44,7 +44,7 @@ import org.luaj.vm2.lib.MathLib; *

  • {@link #ddiv_d(double, double)}
  • *
  • {@link #dmod(double, double)}
  • *
  • {@link #dmod_d(double, double)}
  • - * + * *

    * @see LuaValue * @see LuaNumber @@ -97,7 +97,7 @@ public class LuaDouble extends LuaNumber { } public boolean islong() { - return v == (long) v; + return v == (long) v; } public byte tobyte() { return (byte) (long) v; } @@ -158,12 +158,12 @@ public class LuaDouble extends LuaNumber { /** Divide two double numbers according to lua math, and return a {@link LuaValue} result. * @param lhs Left-hand-side of the division. * @param rhs Right-hand-side of the division. - * @return {@link LuaValue} for the result of the division, + * @return {@link LuaValue} for the result of the division, * taking into account positive and negiative infinity, and Nan - * @see #ddiv_d(double, double) + * @see #ddiv_d(double, double) */ public static LuaValue ddiv(double lhs, double rhs) { - return rhs!=0? valueOf( lhs / rhs ): lhs>0? POSINF: lhs==0? NAN: NEGINF; + return rhs!=0? valueOf( lhs / rhs ): lhs>0? POSINF: lhs==0? NAN: NEGINF; } /** Divide two double numbers according to lua math, and return a double result. @@ -173,15 +173,15 @@ public class LuaDouble extends LuaNumber { * @see #ddiv(double, double) */ public static double ddiv_d(double lhs, double rhs) { - return rhs!=0? lhs / rhs: lhs>0? Double.POSITIVE_INFINITY: lhs==0? Double.NaN: Double.NEGATIVE_INFINITY; + return rhs!=0? lhs / rhs: lhs>0? Double.POSITIVE_INFINITY: lhs==0? Double.NaN: Double.NEGATIVE_INFINITY; } /** Take modulo double numbers according to lua math, and return a {@link LuaValue} result. * @param lhs Left-hand-side of the modulo. * @param rhs Right-hand-side of the modulo. - * @return {@link LuaValue} for the result of the modulo, + * @return {@link LuaValue} for the result of the modulo, * using lua's rules for modulo - * @see #dmod_d(double, double) + * @see #dmod_d(double, double) */ public static LuaValue dmod(double lhs, double rhs) { if (rhs == 0 || lhs == Double.POSITIVE_INFINITY || lhs == Double.NEGATIVE_INFINITY) return NAN; @@ -197,7 +197,7 @@ public class LuaDouble extends LuaNumber { /** Take modulo for double numbers according to lua math, and return a double result. * @param lhs Left-hand-side of the modulo. * @param rhs Right-hand-side of the modulo. - * @return double value for the result of the modulo, + * @return double value for the result of the modulo, * using lua's rules for modulo * @see #dmod(double, double) */ @@ -213,28 +213,28 @@ public class LuaDouble extends LuaNumber { } // relational operators - public LuaValue lt( LuaValue rhs ) { return rhs.gt_b(v)? LuaValue.TRUE: FALSE; } + public LuaValue lt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gt_b(v)? TRUE: FALSE) : super.lt(rhs); } public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; } public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; } - public boolean lt_b( LuaValue rhs ) { return rhs.gt_b(v); } + public boolean lt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gt_b(v) : super.lt_b(rhs); } public boolean lt_b( int rhs ) { return v < rhs; } public boolean lt_b( double rhs ) { return v < rhs; } - public LuaValue lteq( LuaValue rhs ) { return rhs.gteq_b(v)? LuaValue.TRUE: FALSE; } + public LuaValue lteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gteq_b(v)? TRUE: FALSE) : super.lteq(rhs); } public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; } public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; } - public boolean lteq_b( LuaValue rhs ) { return rhs.gteq_b(v); } + public boolean lteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gteq_b(v) : super.lteq_b(rhs); } public boolean lteq_b( int rhs ) { return v <= rhs; } public boolean lteq_b( double rhs ) { return v <= rhs; } - public LuaValue gt( LuaValue rhs ) { return rhs.lt_b(v)? LuaValue.TRUE: FALSE; } + public LuaValue gt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lt_b(v)? TRUE: FALSE) : super.gt(rhs); } public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; } public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; } - public boolean gt_b( LuaValue rhs ) { return rhs.lt_b(v); } + public boolean gt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lt_b(v) : super.gt_b(rhs); } public boolean gt_b( int rhs ) { return v > rhs; } public boolean gt_b( double rhs ) { return v > rhs; } - public LuaValue gteq( LuaValue rhs ) { return rhs.lteq_b(v)? LuaValue.TRUE: FALSE; } + public LuaValue gteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lteq_b(v)? TRUE: FALSE) : super.gteq(rhs); } public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; } public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; } - public boolean gteq_b( LuaValue rhs ) { return rhs.lteq_b(v); } + public boolean gteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lteq_b(v) : super.gteq_b(rhs); } public boolean gteq_b( int rhs ) { return v >= rhs; } public boolean gteq_b( double rhs ) { return v >= rhs; } @@ -245,7 +245,7 @@ public class LuaDouble extends LuaNumber { if ( v == 0.0 ) // never occurs on J2ME return (JavaCompat.INSTANCE.doubleToRawLongBits(v)<0? "-0": "0"); long l = (long) v; - if ( l == v ) + if ( l == v ) return Long.toString(l); if ( Double.isNaN(v) ) return (JavaCompat.INSTANCE.doubleToRawLongBits(v)<0? JSTR_NEGNAN: JSTR_NAN); @@ -271,11 +271,11 @@ public class LuaDouble extends LuaNumber { } public LuaNumber optnumber(LuaNumber defval) { - return this; + return this; } public boolean isnumber() { - return true; + return true; } public boolean isstring() { @@ -290,14 +290,14 @@ public class LuaDouble extends LuaNumber { public LuaNumber checknumber() { return this; } public double checkdouble() { return v; } - public String checkjstring() { + public String checkjstring() { return tojstring(); } - public LuaString checkstring() { + public LuaString checkstring() { return LuaString.valueOf(tojstring()); } public boolean isvalidkey() { return !Double.isNaN(v); - } + } } diff --git a/src/core/org/luaj/vm2/LuaFunction.java b/src/core/org/luaj/vm2/LuaFunction.java index 2730952e..83bee86d 100644 --- a/src/core/org/luaj/vm2/LuaFunction.java +++ b/src/core/org/luaj/vm2/LuaFunction.java @@ -22,14 +22,14 @@ package org.luaj.vm2; -/** - * Base class for functions implemented in Java. +/** + * Base class for functions implemented in Java. *

    - * Direct subclass include {@link org.luaj.vm2.lib.LibFunction} - * which is the base class for - * all built-in library functions coded in Java, - * and {@link LuaClosure}, which represents a lua closure - * whose bytecode is interpreted when the function is invoked. + * Direct subclass include {@link org.luaj.vm2.lib.LibFunction} + * which is the base class for + * all built-in library functions coded in Java, + * and {@link LuaClosure}, which represents a lua closure + * whose bytecode is interpreted when the function is invoked. * @see LuaValue * @see LuaClosure * @see org.luaj.vm2.lib.LibFunction @@ -57,11 +57,11 @@ public class LuaFunction extends LuaValue { } public LuaFunction optfunction(LuaFunction defval) { - return this; + return this; } - public LuaValue getmetatable() { - return s_metatable; + public LuaValue getmetatable() { + return s_metatable; } public String tojstring() { @@ -72,12 +72,15 @@ public class LuaFunction extends LuaValue { return valueOf(tojstring()); } - /** Return the last part of the class name, to be used as a function name in tojstring and elsewhere. + /** Return the last part of the class name, to be used as a function name in tojstring and elsewhere. * @return String naming the last part of the class name after the last dot (.) or dollar sign ($). + * If the first character is '_', it is skipped. */ public String classnamestub() { String s = getClass().getName(); - return s.substring(Math.max(s.lastIndexOf('.'),s.lastIndexOf('$'))+1); + int offset = Math.max(s.lastIndexOf('.'), s.lastIndexOf('$')) + 1; + if (s.charAt(offset) == '_') offset++; + return s.substring(offset); } /** Return a human-readable name for this function. Returns the last part of the class name by default. diff --git a/src/core/org/luaj/vm2/LuaInteger.java b/src/core/org/luaj/vm2/LuaInteger.java index 6c4cb7ba..e5e651dc 100644 --- a/src/core/org/luaj/vm2/LuaInteger.java +++ b/src/core/org/luaj/vm2/LuaInteger.java @@ -24,14 +24,14 @@ package org.luaj.vm2; import org.luaj.vm2.lib.MathLib; /** - * Extension of {@link LuaNumber} which can hold a Java int as its value. + * Extension of {@link LuaNumber} which can hold a Java int as its value. *

    - * These instance are not instantiated directly by clients, but indirectly + * These instance are not instantiated directly by clients, but indirectly * via the static functions {@link LuaValue#valueOf(int)} or {@link LuaValue#valueOf(double)} - * functions. This ensures that policies regarding pooling of instances are - * encapsulated. + * functions. This ensures that policies regarding pooling of instances are + * encapsulated. *

    - * There are no API's specific to LuaInteger that are useful beyond what is already + * There are no API's specific to LuaInteger that are useful beyond what is already * exposed in {@link LuaValue}. * * @see LuaValue @@ -61,16 +61,16 @@ public class LuaInteger extends LuaNumber { */ public static LuaNumber valueOf(long l) { int i = (int) l; - return l==i? (i<=255 && i>=-256? intValues[i+256]: - (LuaNumber) new LuaInteger(i)): + return l==i? (i<=255 && i>=-256? intValues[i+256]: + (LuaNumber) new LuaInteger(i)): (LuaNumber) LuaDouble.valueOf(l); } /** The value being held by this instance. */ public final int v; - /** - * Package protected constructor. + /** + * Package protected constructor. * @see LuaValue#valueOf(int) **/ LuaInteger(int i) { @@ -103,15 +103,15 @@ public class LuaInteger extends LuaNumber { } public LuaString optstring(LuaString defval) { - return LuaString.valueOf(Integer.toString(v)); + return LuaString.valueOf(Integer.toString(v)); } public LuaValue tostring() { - return LuaString.valueOf(Integer.toString(v)); + return LuaString.valueOf(Integer.toString(v)); } - public String optjstring(String defval) { - return Integer.toString(v); + public String optjstring(String defval) { + return Integer.toString(v); } public LuaInteger checkinteger() { @@ -172,48 +172,48 @@ public class LuaInteger extends LuaNumber { public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs,v); } // relational operators - public LuaValue lt( LuaValue rhs ) { return rhs.gt_b(v)? TRUE: FALSE; } + public LuaValue lt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gt_b(v)? TRUE: FALSE) : super.lt(rhs); } public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; } public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; } - public boolean lt_b( LuaValue rhs ) { return rhs.gt_b(v); } + public boolean lt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gt_b(v) : super.lt_b(rhs); } public boolean lt_b( int rhs ) { return v < rhs; } public boolean lt_b( double rhs ) { return v < rhs; } - public LuaValue lteq( LuaValue rhs ) { return rhs.gteq_b(v)? TRUE: FALSE; } + public LuaValue lteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gteq_b(v)? TRUE: FALSE) : super.lteq(rhs); } public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; } public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; } - public boolean lteq_b( LuaValue rhs ) { return rhs.gteq_b(v); } + public boolean lteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gteq_b(v) : super.lteq_b(rhs); } public boolean lteq_b( int rhs ) { return v <= rhs; } public boolean lteq_b( double rhs ) { return v <= rhs; } - public LuaValue gt( LuaValue rhs ) { return rhs.lt_b(v)? TRUE: FALSE; } + public LuaValue gt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lt_b(v)? TRUE: FALSE) : super.gt(rhs); } public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; } public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; } - public boolean gt_b( LuaValue rhs ) { return rhs.lt_b(v); } + public boolean gt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lt_b(v) : super.gt_b(rhs); } public boolean gt_b( int rhs ) { return v > rhs; } public boolean gt_b( double rhs ) { return v > rhs; } - public LuaValue gteq( LuaValue rhs ) { return rhs.lteq_b(v)? TRUE: FALSE; } + public LuaValue gteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lteq_b(v)? TRUE: FALSE) : super.gteq(rhs); } public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; } public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; } - public boolean gteq_b( LuaValue rhs ) { return rhs.lteq_b(v); } + public boolean gteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lteq_b(v) : super.gteq_b(rhs); } public boolean gteq_b( int rhs ) { return v >= rhs; } public boolean gteq_b( double rhs ) { return v >= rhs; } // string comparison public int strcmp( LuaString rhs ) { typerror("attempt to compare number with string"); return 0; } - public int checkint() { - return v; + public int checkint() { + return v; } public long checklong() { - return v; + return v; } public double checkdouble() { return v; } - public String checkjstring() { - return String.valueOf(v); + public String checkjstring() { + return String.valueOf(v); } - public LuaString checkstring() { - return valueOf( String.valueOf(v) ); + public LuaString checkstring() { + return valueOf( String.valueOf(v) ); } } diff --git a/src/core/org/luaj/vm2/LuaString.java b/src/core/org/luaj/vm2/LuaString.java index e9cf8ef0..6c64d559 100644 --- a/src/core/org/luaj/vm2/LuaString.java +++ b/src/core/org/luaj/vm2/LuaString.java @@ -31,28 +31,28 @@ import java.io.PrintStream; import org.luaj.vm2.lib.MathLib; /** - * Subclass of {@link LuaValue} for representing lua strings. + * Subclass of {@link LuaValue} for representing lua strings. *

    - * Because lua string values are more nearly sequences of bytes than + * 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. + * implementation holds the string value in an internal byte array. *

    - * {@link LuaString} values are not considered mutable once constructed, + * {@link LuaString} values are not considered mutable once constructed, * so multiple {@link LuaString} values can chare a single byte array. *

    * 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, + * 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. *

    * Because of this pooling, users of LuaString must not directly alter the * bytes in a LuaString, or undefined behavior will result. *

    - * When Java Strings are used to initialize {@link LuaString} data, the UTF8 encoding is assumed. - * The functions + * When Java Strings are used to initialize {@link LuaString} data, the UTF8 encoding is assumed. + * The functions * {@link #lengthAsUtf8(char[])}, - * {@link #encodeToUtf8(char[], int, byte[], int)}, and - * {@link #decodeAsUtf8(byte[], int, int)} + * {@link #encodeToUtf8(char[], int, byte[], int)}, and + * {@link #decodeAsUtf8(byte[], int, int)} * are used to convert back and forth between UTF8 byte arrays and character arrays. * * @see LuaValue @@ -63,15 +63,15 @@ public class LuaString extends LuaValue { /** The singleton instance for string metatables that forwards to the string functions. * Typically, this is set to the string metatable as a side effect of loading the string - * library, and is read-write to provide flexible behavior by default. When used in a + * library, and is read-write to provide flexible behavior by default. When used in a * server environment where there may be roge scripts, this should be replaced with a * read-only table since it is shared across all lua code in this Java VM. */ public static LuaValue s_metatable; /** The bytes for the string. These must not be mutated directly because - * the backing may be shared by multiple LuaStrings, and the hash code is - * computed only at construction time. + * the backing may be shared by multiple LuaStrings, and the hash code is + * computed only at construction time. * It is exposed only for performance and legacy reasons. */ public final byte[] m_bytes; @@ -84,29 +84,29 @@ public class LuaString extends LuaValue { /** The hashcode for this string. Computed at construct time. */ private final int m_hashcode; - /** Size of cache of recent short strings. This is the maximum number of LuaStrings that + /** Size of cache of recent short strings. This is the maximum number of LuaStrings that * will be retained in the cache of recent short strings. Exposed to package for testing. */ static final int RECENT_STRINGS_CACHE_SIZE = 128; - /** Maximum length of a string to be considered for recent short strings caching. + /** Maximum length of a string to be considered for recent short strings caching. * This effectively limits the total memory that can be spent on the recent strings cache, - * because no LuaString whose backing exceeds this length will be put into the cache. + * because no LuaString whose backing exceeds this length will be put into the cache. * Exposed to package for testing. */ static final int RECENT_STRINGS_MAX_LENGTH = 32; - /** Simple cache of recently created strings that are short. - * This is simply a list of strings, indexed by their hash codes modulo the cache size - * that have been recently constructed. If a string is being constructed frequently - * from different contexts, it will generally show up as a cache hit and resolve + /** Simple cache of recently created strings that are short. + * This is simply a list of strings, indexed by their hash codes modulo the cache size + * that have been recently constructed. If a string is being constructed frequently + * from different contexts, it will generally show up as a cache hit and resolve * to the same value. */ private static final class RecentShortStrings { - private static final LuaString recent_short_strings[] = + private static final LuaString recent_short_strings[] = new LuaString[RECENT_STRINGS_CACHE_SIZE]; } /** - * Get a {@link LuaString} instance whose bytes match - * the supplied Java String using the UTF8 encoding. + * 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 */ @@ -120,7 +120,7 @@ public class LuaString extends LuaValue { /** Construct a {@link LuaString} for a portion of a byte array. *

    * The array is first be used as the backing for this object, so clients must not change contents. - * If the supplied value for 'len' is more than half the length of the container, the + * If the supplied value for 'len' is more than half the length of the container, the * supplied byte array will be used as the backing, otherwise the bytes will be copied to a * new byte array, and cache lookup may be performed. *

    @@ -172,11 +172,11 @@ public class LuaString extends LuaValue { /** Construct a {@link LuaString} using the supplied characters as byte values. *

    - * Only the low-order 8-bits of each character are used, the remainder is ignored. + * Only the low-order 8-bits of each character are used, the remainder is ignored. *

    - * 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 + * 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) { return valueOf(bytes, 0, bytes.length); @@ -184,11 +184,11 @@ public class LuaString extends LuaValue { /** Construct a {@link LuaString} using the supplied characters as byte values. *

    - * Only the low-order 8-bits of each character are used, the remainder is ignored. + * Only the low-order 8-bits of each character are used, the remainder is ignored. *

    - * 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 + * 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 off, int len) { byte[] b = new byte[len]; @@ -215,7 +215,7 @@ public class LuaString extends LuaValue { * The LuaString returned will either be a new LuaString containing the byte array, * or be an existing LuaString used already having the same value. *

    - * The caller must not mutate the contents of the byte array after this call, as + * The caller must not mutate the contents of the byte array after this call, as * it may be used elsewhere due to recent short string caching. * @param bytes byte buffer * @return {@link LuaString} wrapping the byte buffer @@ -241,11 +241,11 @@ public class LuaString extends LuaValue { } public boolean isstring() { - return true; + return true; } - public LuaValue getmetatable() { - return s_metatable; + public LuaValue getmetatable() { + return s_metatable; } public int type() { @@ -289,20 +289,20 @@ public class LuaString extends LuaValue { public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs, checkarith()); } // relational operators, these only work with other strings - public LuaValue lt( LuaValue rhs ) { return rhs.strcmp(this)>0? LuaValue.TRUE: FALSE; } - public boolean lt_b( LuaValue rhs ) { return rhs.strcmp(this)>0; } + public LuaValue lt( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)>0? LuaValue.TRUE: FALSE) : super.lt(rhs); } + public boolean lt_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)>0 : super.lt_b(rhs); } public boolean lt_b( int rhs ) { typerror("attempt to compare string with number"); return false; } public boolean lt_b( double rhs ) { typerror("attempt to compare string with number"); return false; } - public LuaValue lteq( LuaValue rhs ) { return rhs.strcmp(this)>=0? LuaValue.TRUE: FALSE; } - public boolean lteq_b( LuaValue rhs ) { return rhs.strcmp(this)>=0; } + public LuaValue lteq( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)>=0? LuaValue.TRUE: FALSE) : super.lteq(rhs); } + public boolean lteq_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)>=0 : super.lteq_b(rhs); } public boolean lteq_b( int rhs ) { typerror("attempt to compare string with number"); return false; } public boolean lteq_b( double rhs ) { typerror("attempt to compare string with number"); return false; } - public LuaValue gt( LuaValue rhs ) { return rhs.strcmp(this)<0? LuaValue.TRUE: FALSE; } - public boolean gt_b( LuaValue rhs ) { return rhs.strcmp(this)<0; } + public LuaValue gt( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)<0? LuaValue.TRUE: FALSE) : super.gt(rhs); } + public boolean gt_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)<0 : super.gt_b(rhs); } public boolean gt_b( int rhs ) { typerror("attempt to compare string with number"); return false; } public boolean gt_b( double rhs ) { typerror("attempt to compare string with number"); return false; } - public LuaValue gteq( LuaValue rhs ) { return rhs.strcmp(this)<=0? LuaValue.TRUE: FALSE; } - public boolean gteq_b( LuaValue rhs ) { return rhs.strcmp(this)<=0; } + public LuaValue gteq( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)<=0? LuaValue.TRUE: FALSE) : super.gteq(rhs); } + public boolean gteq_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)<=0 : super.gteq_b(rhs); } public boolean gteq_b( int rhs ) { typerror("attempt to compare string with number"); return false; } public boolean gteq_b( double rhs ) { typerror("attempt to compare string with number"); return false; } @@ -310,14 +310,14 @@ public class LuaString extends LuaValue { public LuaValue concat(LuaValue rhs) { return rhs.concatTo(this); } public Buffer concat(Buffer rhs) { return rhs.concatTo(this); } public LuaValue concatTo(LuaNumber lhs) { return concatTo(lhs.strvalue()); } - public LuaValue concatTo(LuaString lhs) { + public LuaValue concatTo(LuaString lhs) { byte[] b = new byte[lhs.m_length+this.m_length]; System.arraycopy(lhs.m_bytes, lhs.m_offset, b, 0, lhs.m_length); System.arraycopy(this.m_bytes, this.m_offset, b, lhs.m_length, this.m_length); return valueUsing(b, 0, b.length); } - // string comparison + // string comparison public int strcmp(LuaValue lhs) { return -lhs.strcmp(this); } public int strcmp(LuaString rhs) { for ( int i=0, j=0; i=0 ) + while ( --n>=0 ) if ( a[i++]!=b[j++] ) return false; return true; @@ -535,8 +535,8 @@ public class LuaString extends LuaValue { return luaByte( index ); } - public String checkjstring() { - return tojstring(); + public String checkjstring() { + return tojstring(); } public LuaString checkstring() { @@ -552,7 +552,7 @@ public class LuaString extends LuaValue { } /** - * 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 @@ -626,12 +626,12 @@ public class LuaString extends LuaValue { /** - * 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 + * @return Java String corresponding to the value of bytes interpreted using UTF8 * @see #lengthAsUtf8(char[]) * @see #encodeToUtf8(char[], int, byte[], int) * @see #isValidUtf8() @@ -692,7 +692,7 @@ public class LuaString extends LuaValue { /** * Encode the given Java string as UTF-8 bytes, writing the result to bytes - * starting at offset. + * starting at offset. *

    * The string should be measured first with lengthAsUtf8 * to make sure the given byte array is large enough. @@ -759,22 +759,22 @@ public class LuaString extends LuaValue { // --------------------- number conversion ----------------------- - /** - * convert to a number using baee 10 or base 16 if it starts with '0x', + /** + * convert to a number using baee 10 or base 16 if it starts with '0x', * or NIL if it can't be converted * @return IntValue, DoubleValue, or NIL depending on the content of the string. - * @see LuaValue#tonumber() + * @see LuaValue#tonumber() */ public LuaValue tonumber() { double d = scannumber(); return Double.isNaN(d)? NIL: valueOf(d); } - /** + /** * convert to a number using a supplied base, or NIL if it can't be converted * @param base the base to use, such as 10 * @return IntValue, DoubleValue, or NIL depending on the content of the string. - * @see LuaValue#tonumber() + * @see LuaValue#tonumber() */ public LuaValue tonumber( int base ) { double d = scannumber( base ); @@ -800,7 +800,7 @@ public class LuaString extends LuaValue { /** * Convert to a number in base 10, or base 16 if the string starts with '0x', * or return Double.NaN if it cannot be converted to a number. - * @return double value if conversion is valid, or Double.NaN if not + * @return double value if conversion is valid, or Double.NaN if not */ public double scannumber() { int i = m_offset, j = m_offset + m_length; @@ -863,10 +863,10 @@ public class LuaString extends LuaValue { return sgn * m * MathLib.dpow_d(2.0, e); } - /** + /** * Convert to a number in a base, or return Double.NaN if not a number. * @param base the base to use between 2 and 36 - * @return double value if conversion is valid, or Double.NaN if not + * @return double value if conversion is valid, or Double.NaN if not */ public double scannumber(int base) { if ( base < 2 || base > 36 ) @@ -884,7 +884,7 @@ public class LuaString extends LuaValue { * @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, + * @return double value if conversion is valid, * or Double.NaN if not */ private double scanlong( int base, int start, int end ) { @@ -895,7 +895,7 @@ public class LuaString extends LuaValue { int digit = m_bytes[i] - (base<=10||(m_bytes[i]>='0'&&m_bytes[i]<='9')? '0': m_bytes[i]>='A'&&m_bytes[i]<='Z'? ('A'-10): ('a'-10)); if ( digit < 0 || digit >= base ) - return Double.NaN; + return Double.NaN; x = x * base + digit; if ( x < 0 ) return Double.NaN; // overflow @@ -907,7 +907,7 @@ public class LuaString extends LuaValue { * Scan and convert a double value, or return Double.NaN if not a double. * @param start the index to start searching from * @param end the first index beyond the search range - * @return double value if conversion is valid, + * @return double value if conversion is valid, * or Double.NaN if not */ private double scandouble(int start, int end) { @@ -930,7 +930,7 @@ public class LuaString extends LuaValue { c[i-start] = (char) m_bytes[i]; try { return Double.parseDouble(new String(c)); - } catch ( Exception e ) { + } catch ( Exception e ) { return Double.NaN; } } diff --git a/src/core/org/luaj/vm2/LuaTable.java b/src/core/org/luaj/vm2/LuaTable.java index d95e261c..a35dcc3f 100644 --- a/src/core/org/luaj/vm2/LuaTable.java +++ b/src/core/org/luaj/vm2/LuaTable.java @@ -25,23 +25,23 @@ import java.lang.ref.WeakReference; import java.util.Vector; /** - * Subclass of {@link LuaValue} for representing lua tables. + * Subclass of {@link LuaValue} for representing lua tables. *

    * Almost all API's implemented in {@link LuaTable} are defined and documented in {@link LuaValue}. *

    * If a table is needed, the one of the type-checking functions can be used such as - * {@link #istable()}, + * {@link #istable()}, * {@link #checktable()}, or - * {@link #opttable(LuaTable)} + * {@link #opttable(LuaTable)} *

    - * The main table operations are defined on {@link LuaValue} + * The main table operations are defined on {@link LuaValue} * for getting and setting values with and without metatag processing: *

    *

    * To iterate over key-value pairs from Java, use @@ -56,7 +56,7 @@ import java.util.Vector; * }}

    * *

    - * As with other types, {@link LuaTable} instances should be constructed via one of the table constructor + * As with other types, {@link LuaTable} instances should be constructed via one of the table constructor * methods on {@link LuaValue}: *