13 Commits

Author SHA1 Message Date
Enyby
6694c375c9 Fix build errors for j2me. #32 2019-03-09 17:38:32 +02:00
Enyby
e70eb5edc2 Fix build bug. #32 2019-03-09 15:49:56 +02:00
Enyby
9688d3c5fc Remove libs dependency from PackageLib. 2019-01-13 19:23:44 +02:00
Enyby
6f5af581e8 Fix string.gsub for invalid use '%' in replacement string
Check code:
```
print(pcall(load('string.gsub("test", "%S", "A%")')))
print(pcall(load('string.gsub("test", "%S", "%A")')))
```
2019-01-03 18:09:00 +02:00
Enyby
870aee2cae Improved opt methods for numbers in LuaString 2018-12-29 19:49:43 +02:00
Enyby
c2ec9edf39 Deny use NaN as index in rawset. 2018-12-24 22:34:49 +02:00
Enyby
cfb3aaca61 Fix math.min and math.max.
Now similar to native Lua and reference: `Returns the argument with the maximum value, according to the Lua operator <. (integer/float) `
2018-12-24 20:52:23 +02:00
Enyby
4105cebf1e Fix math.fmod for int values. 2018-12-24 20:37:39 +02:00
Enyby
339f004eb7 More compat with lua tests. 2018-12-24 19:30:11 +02:00
Enyby
05a604645d Fix modulo for edge cases.
Reference code:
```
for i,lhs in ipairs({-math.huge, -10.0, 0.0, 10.0, math.huge}) do
for j,rhs in ipairs({-math.huge, -10.0, 0.0, 10.0, math.huge}) do
print(lhs, rhs, lhs % rhs)
end
end
```
2018-12-24 18:30:35 +02:00
Enyby
63ead7aac7 Fix string.format for long integers. 2018-12-24 11:45:06 +02:00
Enyby
c9ba2d4bb1 Fix math.modf for inf/-inf and int values. 2018-12-23 17:48:31 +02:00
Enyby
92cee0812d Fix JSE math.log for second arg. 2018-12-23 17:06:34 +02:00
17 changed files with 446 additions and 396 deletions

View File

@@ -11,13 +11,13 @@ import org.luaj.vm2.lib.Bit32Lib;
import org.luaj.vm2.lib.CoroutineLib;
import org.luaj.vm2.lib.PackageLib;
import org.luaj.vm2.lib.ResourceFinder;
import org.luaj.vm2.lib.StringLib;
import org.luaj.vm2.lib.TableLib;
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
import org.luaj.vm2.lib.jse.JseBaseLib;
import org.luaj.vm2.lib.jse.JseIoLib;
import org.luaj.vm2.lib.jse.JseMathLib;
import org.luaj.vm2.lib.jse.JseOsLib;
import org.luaj.vm2.lib.jse.JseStringLib;
import org.luaj.vm2.lib.jse.LuajavaLib;
/**
@@ -76,7 +76,7 @@ public class SampleApplet extends Applet implements ResourceFinder {
globals.load(new PackageLib());
globals.load(new Bit32Lib());
globals.load(new TableLib());
globals.load(new StringLib());
globals.load(new JseStringLib());
globals.load(new CoroutineLib());
globals.load(new JseMathLib());
globals.load(new JseIoLib());

View File

@@ -1,7 +1,21 @@
import org.luaj.vm2.*;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.LuaBoolean;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaThread;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.*;
import org.luaj.vm2.lib.jse.*;
import org.luaj.vm2.lib.Bit32Lib;
import org.luaj.vm2.lib.DebugLib;
import org.luaj.vm2.lib.PackageLib;
import org.luaj.vm2.lib.TableLib;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;
import org.luaj.vm2.lib.jse.JseBaseLib;
import org.luaj.vm2.lib.jse.JseMathLib;
import org.luaj.vm2.lib.jse.JseStringLib;
/** Simple program that illustrates basic sand-boxing of client scripts
* in a server environment.
@@ -29,7 +43,7 @@ public class SampleSandboxed {
server_globals = new Globals();
server_globals.load(new JseBaseLib());
server_globals.load(new PackageLib());
server_globals.load(new StringLib());
server_globals.load(new JseStringLib());
// To load scripts, we occasionally need a math library in addition to compiler support.
// To limit scripts using the debug library, they must be closures, so we only install LuaC.
@@ -82,7 +96,7 @@ public class SampleSandboxed {
user_globals.load(new PackageLib());
user_globals.load(new Bit32Lib());
user_globals.load(new TableLib());
user_globals.load(new StringLib());
user_globals.load(new JseStringLib());
user_globals.load(new JseMathLib());
// This library is dangerous as it gives unfettered access to the

View File

@@ -177,7 +177,14 @@ public class LuaDouble extends LuaNumber {
* @see #dmod_d(double, double)
*/
public static LuaValue dmod(double lhs, double rhs) {
return rhs!=0? valueOf( lhs-rhs*Math.floor(lhs/rhs) ): NAN;
if (rhs == 0 || lhs == Double.POSITIVE_INFINITY || lhs == Double.NEGATIVE_INFINITY) return NAN;
if (rhs == Double.POSITIVE_INFINITY) {
return lhs < 0 ? POSINF : valueOf(lhs);
}
if (rhs == Double.NEGATIVE_INFINITY) {
return lhs > 0 ? NEGINF : valueOf(lhs);
}
return valueOf( lhs-rhs*Math.floor(lhs/rhs) );
}
/** Take modulo for double numbers according to lua math, and return a double result.
@@ -188,7 +195,14 @@ public class LuaDouble extends LuaNumber {
* @see #dmod(double, double)
*/
public static double dmod_d(double lhs, double rhs) {
return rhs!=0? lhs-rhs*Math.floor(lhs/rhs): Double.NaN;
if (rhs == 0 || lhs == Double.POSITIVE_INFINITY || lhs == Double.NEGATIVE_INFINITY) return Double.NaN;
if (rhs == Double.POSITIVE_INFINITY) {
return lhs < 0 ? Double.POSITIVE_INFINITY : lhs;
}
if (rhs == Double.NEGATIVE_INFINITY) {
return lhs > 0 ? Double.NEGATIVE_INFINITY : lhs;
}
return lhs-rhs*Math.floor(lhs/rhs);
}
// relational operators

View File

@@ -391,23 +391,23 @@ public class LuaString extends LuaValue {
public short toshort() { return (short) toint(); }
public double optdouble(double defval) {
return checknumber().checkdouble();
return checkdouble();
}
public int optint(int defval) {
return checknumber().checkint();
return checkint();
}
public LuaInteger optinteger(LuaInteger defval) {
return checknumber().checkinteger();
return checkinteger();
}
public long optlong(long defval) {
return checknumber().checklong();
return checklong();
}
public LuaNumber optnumber(LuaNumber defval) {
return checknumber().checknumber();
return checknumber();
}
public LuaString optstring(LuaString defval) {

View File

@@ -643,7 +643,7 @@ public class LuaValue extends Varargs {
* @see #isnumber()
* @see #TNUMBER
*/
public double optdouble(double defval) { argerror("double"); return 0; }
public double optdouble(double defval) { argerror("number"); return 0; }
/** Check that optional argument is a function and return as {@link LuaFunction}
* <p>
@@ -855,7 +855,7 @@ public class LuaValue extends Varargs {
* @see #optdouble(double)
* @see #TNUMBER
*/
public double checkdouble() { argerror("double"); return 0; }
public double checkdouble() { argerror("number"); return 0; }
/** Check that the value is a function , or throw {@link LuaError} if not
* <p>

View File

@@ -299,7 +299,8 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
}
public LuaValue call(LuaValue table, LuaValue index, LuaValue value) {
LuaTable t = table.checktable();
t.rawset(index.checknotnil(), value);
if (!index.isvalidkey()) argerror(2, "value");
t.rawset(index, value);
return t;
}
}

View File

@@ -71,7 +71,7 @@ public class Bit32Lib extends TwoArgFunction {
"arshift", "lrotate", "lshift", "rrotate", "rshift"
});
env.set("bit32", t);
env.get("package").get("loaded").set("bit32", t);
if (!env.get("package").isnil()) env.get("package").get("loaded").set("bit32", t);
return t;
}

View File

@@ -82,7 +82,7 @@ public class CoroutineLib extends TwoArgFunction {
coroutine.set("yield", new yield());
coroutine.set("wrap", new wrap());
env.set("coroutine", coroutine);
env.get("package").get("loaded").set("coroutine", coroutine);
if (!env.get("package").isnil()) env.get("package").get("loaded").set("coroutine", coroutine);
return coroutine;
}

View File

@@ -135,7 +135,7 @@ public class DebugLib extends TwoArgFunction {
debug.set("upvalueid", new upvalueid());
debug.set("upvaluejoin", new upvaluejoin());
env.set("debug", debug);
env.get("package").get("loaded").set("debug", debug);
if (!env.get("package").isnil()) env.get("package").get("loaded").set("debug", debug);
return debug;
}

View File

@@ -256,7 +256,7 @@ public class IoLib extends TwoArgFunction {
// return the table
env.set("io", t);
env.get("package").get("loaded").set("io", t);
if (!env.get("package").isnil()) env.get("package").get("loaded").set("io", t);
return t;
}

View File

@@ -125,7 +125,7 @@ public class MathLib extends TwoArgFunction {
math.set("sqrt", new sqrt());
math.set("tan", new tan());
env.set("math", math);
env.get("package").get("loaded").set("math", math);
if (!env.get("package").isnil()) env.get("package").get("loaded").set("math", math);
return math;
}
@@ -163,10 +163,12 @@ public class MathLib extends TwoArgFunction {
}
}
static final class fmod extends BinaryOp {
protected double call(double x, double y) {
double q = x/y;
return x - y * (q>=0? Math.floor(q): Math.ceil(q));
static final class fmod extends TwoArgFunction {
public LuaValue call(LuaValue xv, LuaValue yv) {
if (xv.islong() && yv.islong()) {
return valueOf(xv.tolong() % yv.tolong());
}
return valueOf(xv.checkdouble() % yv.checkdouble());
}
}
static final class ldexp extends BinaryOp {
@@ -194,27 +196,36 @@ public class MathLib extends TwoArgFunction {
static class max extends VarArgFunction {
public Varargs invoke(Varargs args) {
double m = args.checkdouble(1);
for ( int i=2,n=args.narg(); i<=n; ++i )
m = Math.max(m,args.checkdouble(i));
return valueOf(m);
LuaValue m = args.checkvalue(1);
for ( int i=2,n=args.narg(); i<=n; ++i ) {
LuaValue v = args.checkvalue(i);
if (m.lt_b(v)) m = v;
}
return m;
}
}
static class min extends VarArgFunction {
public Varargs invoke(Varargs args) {
double m = args.checkdouble(1);
for ( int i=2,n=args.narg(); i<=n; ++i )
m = Math.min(m,args.checkdouble(i));
return valueOf(m);
LuaValue m = args.checkvalue(1);
for ( int i=2,n=args.narg(); i<=n; ++i ) {
LuaValue v = args.checkvalue(i);
if (v.lt_b(m)) m = v;
}
return m;
}
}
static class modf extends VarArgFunction {
public Varargs invoke(Varargs args) {
double x = args.checkdouble(1);
LuaValue n = args.arg1();
/* number is its own integer part, no fractional part */
if (n.islong()) return varargsOf(n, valueOf(0.0));
double x = n.checkdouble();
/* integer part (rounds toward zero) */
double intPart = ( x > 0 ) ? Math.floor( x ) : Math.ceil( x );
double fracPart = x - intPart;
/* fractional part (test needed for inf/-inf) */
double fracPart = x == intPart ? 0.0 : x - intPart;
return varargsOf( valueOf(intPart), valueOf(fracPart) );
}
}

View File

@@ -132,7 +132,7 @@ public class OsLib extends TwoArgFunction {
for (int i = 0; i < NAMES.length; ++i)
os.set(NAMES[i], new OsLibFunc(i, NAMES[i]));
env.set("os", os);
env.get("package").get("loaded").set("os", os);
if (!env.get("package").isnil()) env.get("package").get("loaded").set("os", os);
return os;
}

View File

@@ -24,8 +24,8 @@ package org.luaj.vm2.lib;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.luaj.vm2.LuaClosure;
import org.luaj.vm2.Buffer;
import org.luaj.vm2.LuaClosure;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
@@ -49,7 +49,7 @@ import org.luaj.vm2.compiler.DumpState;
* Globals globals = new Globals();
* globals.load(new JseBaseLib());
* globals.load(new PackageLib());
* globals.load(new StringLib());
* globals.load(new JseStringLib());
* System.out.println( globals.get("string").get("upper").call( LuaValue.valueOf("abcde") ) );
* } </pre>
* <p>
@@ -99,7 +99,7 @@ public class StringLib extends TwoArgFunction {
string.set("upper", new upper());
env.set("string", string);
env.get("package").get("loaded").set("string", string);
if (!env.get("package").isnil()) env.get("package").get("loaded").set("string", string);
if (LuaString.s_metatable == null) {
LuaString.s_metatable = LuaValue.tableOf(new LuaValue[] { INDEX, string });
}
@@ -173,7 +173,7 @@ public class StringLib extends TwoArgFunction {
* TODO: port dumping code as optional add-on
*/
static final class dump extends VarArgFunction {
public LuaValue invoke(Varargs args) {
public Varargs invoke(Varargs args) {
LuaValue f = args.checkfunction(1);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
@@ -230,7 +230,7 @@ public class StringLib extends TwoArgFunction {
* This function does not accept string values containing embedded zeros,
* except as arguments to the q option.
*/
static final class format extends VarArgFunction {
final class format extends VarArgFunction {
public Varargs invoke(Varargs args) {
LuaString fmt = args.checkstring( 1 );
final int n = fmt.length();
@@ -261,7 +261,7 @@ public class StringLib extends TwoArgFunction {
break;
case 'i':
case 'd':
fdsc.format( result, args.checkint( arg ) );
fdsc.format( result, args.checklong( arg ) );
break;
case 'o':
case 'u':
@@ -330,7 +330,7 @@ public class StringLib extends TwoArgFunction {
private static final String FLAGS = "-+ #0";
static class FormatDesc {
class FormatDesc {
private boolean leftAdjust;
private boolean zeroPad;
@@ -470,13 +470,7 @@ public class StringLib extends TwoArgFunction {
}
public void format(Buffer buf, double x) {
String out;
try {
out = String.format(src, x);
} catch (Throwable e) {
out = String.valueOf( x );
}
buf.append( out );
buf.append( StringLib.this.format(src, x) );
}
public void format(Buffer buf, LuaString s) {
@@ -486,13 +480,17 @@ public class StringLib extends TwoArgFunction {
buf.append(s);
}
public static final void pad(Buffer buf, char c, int n) {
public final void pad(Buffer buf, char c, int n) {
byte b = (byte)c;
while ( n-- > 0 )
buf.append(b);
}
}
protected String format(String src, double x) {
return String.valueOf(x);
}
/**
* string.gmatch (s, pattern)
*
@@ -877,8 +875,14 @@ public class StringLib extends TwoArgFunction {
lbuf.append( (byte) b );
} else {
++i; // skip ESC
b = (byte) news.luaByte( i );
b = (byte)(i < l ? news.luaByte( i ) : 0);
if ( !Character.isDigit( (char) b ) ) {
if (b != L_ESC) error( "invalid use of '" + (char)L_ESC +
"' in replacement string: after '" + (char)L_ESC +
"' must be '0'-'9' or '" + (char)L_ESC +
"', but found " + (i < l ? "symbol '" + (char)b + "' with code " + b +
" at pos " + (i + 1) :
"end of string"));
lbuf.append( b );
} else if ( b == '0' ) {
lbuf.append( s.substring( soff, e ) );

View File

@@ -70,7 +70,7 @@ public class TableLib extends TwoArgFunction {
table.set("sort", new sort());
table.set("unpack", new unpack());
env.set("table", table);
env.get("package").get("loaded").set("table", table);
if (!env.get("package").isnil()) env.get("package").get("loaded").set("table", table);
return NIL;
}

View File

@@ -98,7 +98,14 @@ public class JseMathLib extends org.luaj.vm2.lib.MathLib {
}
static final class cosh extends UnaryOp { protected double call(double d) { return Math.cosh(d); } }
static final class exp extends UnaryOp { protected double call(double d) { return Math.exp(d); } }
static final class log extends UnaryOp { protected double call(double d) { return Math.log(d); } }
static final class log extends TwoArgFunction {
public LuaValue call(LuaValue x, LuaValue base) {
double nat = Math.log(x.checkdouble());
double b = base.optdouble(Math.E);
if (b != Math.E) nat /= Math.log(b);
return valueOf(nat);
}
}
static final class pow extends BinaryOp { protected double call(double x, double y) { return Math.pow(x, y); } }
static final class sinh extends UnaryOp { protected double call(double d) { return Math.sinh(d); } }
static final class tanh extends UnaryOp { protected double call(double d) { return Math.tanh(d); } }

View File

@@ -23,7 +23,6 @@ package org.luaj.vm2.lib.jse;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.LuaThread;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.compiler.LuaC;
@@ -98,7 +97,7 @@ public class JsePlatform {
globals.load(new PackageLib());
globals.load(new Bit32Lib());
globals.load(new TableLib());
globals.load(new StringLib());
globals.load(new JseStringLib());
globals.load(new CoroutineLib());
globals.load(new JseMathLib());
globals.load(new JseIoLib());

View File

@@ -112,7 +112,7 @@ public class LuajavaLib extends VarArgFunction {
LuaTable t = new LuaTable();
bind( t, this.getClass(), NAMES, BINDCLASS );
env.set("luajava", t);
env.get("package").get("loaded").set("luajava", t);
if (!env.get("package").isnil()) env.get("package").get("loaded").set("luajava", t);
return t;
}
case BINDCLASS: {