Compare commits
1 Commits
topgogo/ma
...
v3.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70cb74b4d6 |
21
LICENSE
21
LICENSE
@@ -1,21 +0,0 @@
|
|||||||
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.
|
|
||||||
@@ -1,24 +1,27 @@
|
|||||||
# This is a fork!
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
<div style="border: 1px dotted red; margin: 1.em 0.5em; font-weight: bold; color: red;">
|
<html>
|
||||||
This repository has been forked from the original CVS sources of Luaj.
|
|
||||||
The commit history has been converted to make sure that the original work of
|
|
||||||
James Roseborough and Ian Farmer is not lost.
|
|
||||||
Unfortunately, I was not able to contact either James or Ian to hand over
|
|
||||||
ownership of the Github organization/repo as I have originally intended to.
|
|
||||||
The community however seems interested enough to continue work on the original
|
|
||||||
sources and therefore I have decided to make sure that any useful pull requests
|
|
||||||
that may add some value to the original code base shall be merged in from now
|
|
||||||
on.<br>
|
|
||||||
-- Benjamin P. Jung, Jan. 26th 2018
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h1>Getting Started with LuaJ</h1>
|
<head>
|
||||||
James Roseborough, Ian Farmer, Version 3.0.2
|
<title>Getting Started with LuaJ</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="http://www.lua.org/lua.css">
|
||||||
|
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h1>
|
||||||
|
<a href="README.html"><img src="http://sourceforge.net/dbimage.php?id=196139" alt="" border="0"></a>
|
||||||
|
|
||||||
|
Getting Started with LuaJ
|
||||||
|
|
||||||
|
</h1>
|
||||||
|
James Roseborough, Ian Farmer, Version 3.0.1
|
||||||
<p>
|
<p>
|
||||||
<small>
|
<small>
|
||||||
Copyright © 2009-2014 Luaj.org.
|
Copyright © 2009-2014 Luaj.org.
|
||||||
Freely available under the terms of the
|
Freely available under the terms of the
|
||||||
<a href="LICENSE">Luaj license</a>.
|
<a href="http://sourceforge.net/dbimage.php?id=196142">Luaj license</a>.
|
||||||
</small>
|
</small>
|
||||||
<hr>
|
<hr>
|
||||||
<p>
|
<p>
|
||||||
@@ -117,7 +120,7 @@ in comparison with the standard C distribution.
|
|||||||
<td>16.794</td>
|
<td>16.794</td>
|
||||||
<td>11.274</td>
|
<td>11.274</td>
|
||||||
<td>Java</td>
|
<td>Java</td>
|
||||||
<td>java -cp luaj-jse-3.0.2.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr>
|
<td>java -cp luaj-jse-3.0.1.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr>
|
||||||
<tr valign="top">
|
<tr valign="top">
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
@@ -127,7 +130,7 @@ in comparison with the standard C distribution.
|
|||||||
<td>36.894</td>
|
<td>36.894</td>
|
||||||
<td>15.163</td>
|
<td>15.163</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>java -cp luaj-jse-3.0.2.jar lua -n fannkuch.lua 10</td></tr>
|
<td>java -cp luaj-jse-3.0.1.jar lua -n fannkuch.lua 10</td></tr>
|
||||||
<tr valign="top">
|
<tr valign="top">
|
||||||
<td>lua</td>
|
<td>lua</td>
|
||||||
<td>5.1.4</td>
|
<td>5.1.4</td>
|
||||||
@@ -183,7 +186,7 @@ It is also faster than Java-lua implementations Jill, Kahlua, and Mochalua for a
|
|||||||
From the main distribution directory line type:
|
From the main distribution directory line type:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
java -cp luaj-jse-3.0.2.jar lua examples/lua/hello.lua
|
java -cp lib/luaj-jse-3.0.1.jar lua examples/lua/hello.lua
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -195,7 +198,7 @@ You should see the following output:
|
|||||||
To see how luaj can be used to acccess most Java API's including swing, try:
|
To see how luaj can be used to acccess most Java API's including swing, try:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
java -cp luaj-jse-3.0.2.jar lua examples/lua/swingapp.lua
|
java -cp lib/luaj-jse-3.0.1.jar lua examples/lua/swingapp.lua
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -210,8 +213,8 @@ Links to sources:<pre>
|
|||||||
From the main distribution directory line type:
|
From the main distribution directory line type:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
java -cp luaj-jse-3.0.2.jar luac examples/lua/hello.lua
|
java -cp lib/luaj-jse-3.0.1.jar luac examples/lua/hello.lua
|
||||||
java -cp luaj-jse-3.0.2.jar lua luac.out
|
java -cp lib/luaj-jse-3.0.1.jar lua luac.out
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -225,8 +228,8 @@ Luaj can compile lua sources or binaries directly to java bytecode if the bcel l
|
|||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
ant bcel-lib
|
ant bcel-lib
|
||||||
java -cp "luaj-jse-3.0.2.jar;lib/bcel-5.2.jar" luajc -s examples/lua -d . hello.lua
|
java -cp "lib/luaj-jse-3.0.1.jar;lib/bcel-5.2.jar" luajc -s examples/lua -d . hello.lua
|
||||||
java -cp "luaj-jse-3.0.2.jar;." lua -l hello
|
java -cp "lib/luaj-jse-3.0.1.jar;." lua -l hello
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -237,7 +240,7 @@ but the compiled classes must be in the class path at runtime, unless runtime ji
|
|||||||
<p>
|
<p>
|
||||||
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-b</em></b> option and providing the <em>bcel</em> library in the class path:
|
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-b</em></b> option and providing the <em>bcel</em> library in the class path:
|
||||||
<pre>
|
<pre>
|
||||||
java -cp "luaj-jse-3.0.2.jar;lib/bcel-5.2.jar" lua -b examples/lua/hello.lua
|
java -cp "lib/luaj-jse-3.0.1.jar;lib/bcel-5.2.jar" lua -b examples/lua/hello.lua
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
@@ -281,7 +284,7 @@ A simple example may be found in
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You must include the library <b>luaj-jse-3.0.2.jar</b> in your class path.
|
You must include the library <b>lib/luaj-jse-3.0.1.jar</b> in your class path.
|
||||||
|
|
||||||
<h2>Run a script in a MIDlet</h2>
|
<h2>Run a script in a MIDlet</h2>
|
||||||
|
|
||||||
@@ -308,7 +311,7 @@ A simple example may be found in
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You must include the library <b>luaj-jme-3.0.2.jar</b> in your midlet jar.
|
You must include the library <b>lib/luaj-jme-3.0.1.jar</b> in your midlet jar.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
An ant script to build and run the midlet is in
|
An ant script to build and run the midlet is in
|
||||||
@@ -338,7 +341,7 @@ You can also look up the engine by language "lua" or mimetypes "text/lua" or "ap
|
|||||||
All standard aspects of script engines including compiled statements are supported.
|
All standard aspects of script engines including compiled statements are supported.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You must include the library <b>luaj-jse-3.0.2.jar</b> in your class path.
|
You must include the library <b>lib/luaj-jse-3.0.1.jar</b> in your class path.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
A working example may be found in
|
A working example may be found in
|
||||||
@@ -349,8 +352,8 @@ A working example may be found in
|
|||||||
To compile and run it using Java 1.6 or higher:
|
To compile and run it using Java 1.6 or higher:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
javac -cp luaj-jse-3.0.2.jar examples/jse/ScriptEngineSample.java
|
javac -cp lib/luaj-jse-3.0.1.jar examples/jse/ScriptEngineSample.java
|
||||||
java -cp "luaj-jse-3.0.2.jar;examples/jse" ScriptEngineSample
|
java -cp "lib/luaj-jse-3.0.1.jar;examples/jse" ScriptEngineSample
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h2>Excluding the lua bytecode compiler</h2>
|
<h2>Excluding the lua bytecode compiler</h2>
|
||||||
@@ -412,7 +415,7 @@ and the math operations include all those supported by Java SE.
|
|||||||
Android applications should use the JsePlatform, and can include the <a href="#luajava">Luajava</a> library
|
Android applications should use the JsePlatform, and can include the <a href="#luajava">Luajava</a> library
|
||||||
to simplify access to underlying Android APIs.
|
to simplify access to underlying Android APIs.
|
||||||
A specialized Globals.finder should be provided to find scripts and data for loading.
|
A specialized Globals.finder should be provided to find scripts and data for loading.
|
||||||
See <a href="examples/android/src/android/LuajView.java">examples/android/src/android/LuajView.java</a>
|
See <a href="examples/android/src/android/LuajView">examples/android/src/android/LuajView</a>
|
||||||
for an example that loads from the "res" Android project directory.
|
for an example that loads from the "res" Android project directory.
|
||||||
The ant build script is <a href="examples/android/build.xml">examples/android/build.xml</a>.
|
The ant build script is <a href="examples/android/build.xml">examples/android/build.xml</a>.
|
||||||
|
|
||||||
@@ -590,7 +593,7 @@ The following lua script will open a swing frame on Java SE:
|
|||||||
See a longer sample in <em>examples/lua/swingapp.lua</em> for details, including a simple animation loop, rendering graphics, mouse and key handling, and image loading.
|
See a longer sample in <em>examples/lua/swingapp.lua</em> for details, including a simple animation loop, rendering graphics, mouse and key handling, and image loading.
|
||||||
Or try running it using:
|
Or try running it using:
|
||||||
<pre>
|
<pre>
|
||||||
java -cp luaj-jse-3.0.2.jar lua examples/lua/swingapp.lua
|
java -cp lib/luaj-jse-3.0.1.jar lua examples/lua/swingapp.lua
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -839,7 +842,7 @@ For JSE projects, add this dependency for the luaj-jse jar:
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.luaj</groupId>
|
<groupId>org.luaj</groupId>
|
||||||
<artifactId>luaj-jse</artifactId>
|
<artifactId>luaj-jse</artifactId>
|
||||||
<version>3.0.2</version>
|
<version>3.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</pre>
|
</pre>
|
||||||
while for JME projects, use the luaj-jme jar:
|
while for JME projects, use the luaj-jme jar:
|
||||||
@@ -847,7 +850,7 @@ while for JME projects, use the luaj-jme jar:
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.luaj</groupId>
|
<groupId>org.luaj</groupId>
|
||||||
<artifactId>luaj-jme</artifactId>
|
<artifactId>luaj-jme</artifactId>
|
||||||
<version>3.0.2</version>
|
<version>3.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@@ -877,7 +880,7 @@ Unit test scripts can be found in these locations
|
|||||||
test/lua/*.lua
|
test/lua/*.lua
|
||||||
test/lua/errors/*.lua
|
test/lua/errors/*.lua
|
||||||
test/lua/perf/*.lua
|
test/lua/perf/*.lua
|
||||||
test/lua/luaj3.0.2-tests.zip
|
test/lua/luaj3.0.1-tests.zip
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h2>Code coverage</h2>
|
<h2>Code coverage</h2>
|
||||||
@@ -927,7 +930,7 @@ Files are no longer hosted at LuaForge.
|
|||||||
<li>Enhance javadoc, put it <a href="docs/api/index.html">in distribution</a>
|
<li>Enhance javadoc, put it <a href="docs/api/index.html">in distribution</a>
|
||||||
and at <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sourceforge.net/api/2.0/</a></li>
|
and at <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sourceforge.net/api/2.0/</a></li>
|
||||||
<li>Major refactor of luajava type coercion logic, improve method selection.</li>
|
<li>Major refactor of luajava type coercion logic, improve method selection.</li>
|
||||||
<li>Add luaj-sources-2.0.2.jar for easier integration into an IDE such as Netbeans </li>
|
<li>Add lib/luaj-sources-2.0.2.jar for easier integration into an IDE such as Netbeans </li>
|
||||||
|
|
||||||
<tr valign="top"><td> <b>2.0.3</b></td><td><ul>
|
<tr valign="top"><td> <b>2.0.3</b></td><td><ul>
|
||||||
<li>Improve coroutine state logic including let unreferenced coroutines be garbage collected </li>
|
<li>Improve coroutine state logic including let unreferenced coroutines be garbage collected </li>
|
||||||
@@ -1014,16 +1017,6 @@ and at <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sour
|
|||||||
<li>Move online docs to <a href="http://luaj.org/luaj/3.0/api/index.html">http://luaj.org/luaj/3.0/api/</a></li>
|
<li>Move online docs to <a href="http://luaj.org/luaj/3.0/api/index.html">http://luaj.org/luaj/3.0/api/</a></li>
|
||||||
<li>Fix os.time() conversions for pm times.</li>
|
<li>Fix os.time() conversions for pm times.</li>
|
||||||
|
|
||||||
<tr valign="top"><td> <b>3.0.2</b></td><td><ul>
|
|
||||||
<li>Fix JsePlatform.luaMain() to provide an "arg" table in the chunk's environment.</li>
|
|
||||||
<li>Let JsePlatform.luaMain() return values returned by the main chunk.</li>
|
|
||||||
<li>Add synchronization to CoerceJavaToLua.COERCIONS map.</li>
|
|
||||||
|
|
||||||
</ul></td></tr>
|
|
||||||
<tr valign="top"><td> <b>3.1.0</b></td><td><ul>
|
|
||||||
<li>Runtime upgrade to Java 8 or newer.</li>
|
|
||||||
<li>Feature: Support Java 21 VirtualThread</li>
|
|
||||||
|
|
||||||
</ul></td></tr>
|
</ul></td></tr>
|
||||||
</table></td></tr></table>
|
</table></td></tr></table>
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<attribute name="jars" default="**/*.jar"/>
|
<attribute name="jars" default="**/*.jar"/>
|
||||||
<sequential>
|
<sequential>
|
||||||
<mkdir dir="lib"/>
|
<mkdir dir="lib"/>
|
||||||
<get src="https://luaj.sourceforge.net/lib/@{zipname}.tar.gz"
|
<get src="http://luaj.sourceforge.net/lib/@{zipname}.tar.gz"
|
||||||
dest="lib/@{zipname}.tar.gz"/>
|
dest="lib/@{zipname}.tar.gz"/>
|
||||||
<gunzip src="lib/@{zipname}.tar.gz" dest="lib/@{zipname}.tar"/>
|
<gunzip src="lib/@{zipname}.tar.gz" dest="lib/@{zipname}.tar"/>
|
||||||
<untar src="lib/@{zipname}.tar" dest="lib" overwrite="true">
|
<untar src="lib/@{zipname}.tar" dest="lib" overwrite="true">
|
||||||
|
|||||||
16
build.xml
16
build.xml
@@ -81,24 +81,18 @@
|
|||||||
<pathelement path="lib/midpapi20.jar"/>
|
<pathelement path="lib/midpapi20.jar"/>
|
||||||
<pathelement path="lib/mmapi.jar"/>
|
<pathelement path="lib/mmapi.jar"/>
|
||||||
</path>
|
</path>
|
||||||
<javac includeantruntime="false" destdir="build/jme/classes" encoding="utf-8" source="1.8" target="1.8"
|
<javac destdir="build/jme/classes" encoding="utf-8" source="1.3" target="1.2" bootclasspathref="wtk-libs"
|
||||||
debug="on"
|
srcdir="build/jme/src"/>
|
||||||
srcdir="build/jme/src">
|
<javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
|
||||||
<classpath refid="wtk-libs"/>
|
|
||||||
</javac>
|
|
||||||
<javac includeantruntime="false" destdir="build/jse/classes" encoding="utf-8" source="1.8" target="1.8"
|
|
||||||
classpath="lib/bcel-5.2.jar"
|
classpath="lib/bcel-5.2.jar"
|
||||||
debug="on"
|
|
||||||
srcdir="build/jse/src"
|
srcdir="build/jse/src"
|
||||||
excludes="**/script/*,**/Lua2Java*,**/server/*,lua*"/>
|
excludes="**/script/*,**/Lua2Java*,**/server/*,lua*"/>
|
||||||
<javac includeantruntime="false" destdir="build/jse/classes" encoding="utf-8" source="1.8" target="1.8"
|
<javac destdir="build/jse/classes" encoding="utf-8" source="1.5" target="1.5"
|
||||||
classpath="build/jse/classes"
|
classpath="build/jse/classes"
|
||||||
debug="on"
|
|
||||||
srcdir="build/jse/src"
|
srcdir="build/jse/src"
|
||||||
includes="**/script/*,**/Lua2Java*,**/server/*"/>
|
includes="**/script/*,**/Lua2Java*,**/server/*"/>
|
||||||
<javac includeantruntime="false" destdir="build/jse/classes" encoding="utf-8" source="1.8" target="1.8"
|
<javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
|
||||||
classpath="build/jse/classes"
|
classpath="build/jse/classes"
|
||||||
debug="on"
|
|
||||||
srcdir="build/jse/src"
|
srcdir="build/jse/src"
|
||||||
includes="lua*"/>
|
includes="lua*"/>
|
||||||
</target>
|
</target>
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ import org.luaj.vm2.lib.Bit32Lib;
|
|||||||
import org.luaj.vm2.lib.CoroutineLib;
|
import org.luaj.vm2.lib.CoroutineLib;
|
||||||
import org.luaj.vm2.lib.PackageLib;
|
import org.luaj.vm2.lib.PackageLib;
|
||||||
import org.luaj.vm2.lib.ResourceFinder;
|
import org.luaj.vm2.lib.ResourceFinder;
|
||||||
|
import org.luaj.vm2.lib.StringLib;
|
||||||
import org.luaj.vm2.lib.TableLib;
|
import org.luaj.vm2.lib.TableLib;
|
||||||
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
|
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
|
||||||
import org.luaj.vm2.lib.jse.JseBaseLib;
|
import org.luaj.vm2.lib.jse.JseBaseLib;
|
||||||
import org.luaj.vm2.lib.jse.JseIoLib;
|
import org.luaj.vm2.lib.jse.JseIoLib;
|
||||||
import org.luaj.vm2.lib.jse.JseMathLib;
|
import org.luaj.vm2.lib.jse.JseMathLib;
|
||||||
import org.luaj.vm2.lib.jse.JseOsLib;
|
import org.luaj.vm2.lib.jse.JseOsLib;
|
||||||
import org.luaj.vm2.lib.jse.JseStringLib;
|
|
||||||
import org.luaj.vm2.lib.jse.LuajavaLib;
|
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 PackageLib());
|
||||||
globals.load(new Bit32Lib());
|
globals.load(new Bit32Lib());
|
||||||
globals.load(new TableLib());
|
globals.load(new TableLib());
|
||||||
globals.load(new JseStringLib());
|
globals.load(new StringLib());
|
||||||
globals.load(new CoroutineLib());
|
globals.load(new CoroutineLib());
|
||||||
globals.load(new JseMathLib());
|
globals.load(new JseMathLib());
|
||||||
globals.load(new JseIoLib());
|
globals.load(new JseIoLib());
|
||||||
|
|||||||
@@ -1,21 +1,7 @@
|
|||||||
import org.luaj.vm2.Globals;
|
import org.luaj.vm2.*;
|
||||||
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.compiler.LuaC;
|
||||||
import org.luaj.vm2.lib.Bit32Lib;
|
import org.luaj.vm2.lib.*;
|
||||||
import org.luaj.vm2.lib.DebugLib;
|
import org.luaj.vm2.lib.jse.*;
|
||||||
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
|
/** Simple program that illustrates basic sand-boxing of client scripts
|
||||||
* in a server environment.
|
* in a server environment.
|
||||||
@@ -43,7 +29,7 @@ public class SampleSandboxed {
|
|||||||
server_globals = new Globals();
|
server_globals = new Globals();
|
||||||
server_globals.load(new JseBaseLib());
|
server_globals.load(new JseBaseLib());
|
||||||
server_globals.load(new PackageLib());
|
server_globals.load(new PackageLib());
|
||||||
server_globals.load(new JseStringLib());
|
server_globals.load(new StringLib());
|
||||||
|
|
||||||
// To load scripts, we occasionally need a math library in addition to compiler support.
|
// 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.
|
// To limit scripts using the debug library, they must be closures, so we only install LuaC.
|
||||||
@@ -96,7 +82,7 @@ public class SampleSandboxed {
|
|||||||
user_globals.load(new PackageLib());
|
user_globals.load(new PackageLib());
|
||||||
user_globals.load(new Bit32Lib());
|
user_globals.load(new Bit32Lib());
|
||||||
user_globals.load(new TableLib());
|
user_globals.load(new TableLib());
|
||||||
user_globals.load(new JseStringLib());
|
user_globals.load(new StringLib());
|
||||||
user_globals.load(new JseMathLib());
|
user_globals.load(new JseMathLib());
|
||||||
|
|
||||||
// This library is dangerous as it gives unfettered access to the
|
// This library is dangerous as it gives unfettered access to the
|
||||||
|
|||||||
@@ -155,6 +155,7 @@ public class LoadState {
|
|||||||
private static final LuaValue[] NOVALUES = {};
|
private static final LuaValue[] NOVALUES = {};
|
||||||
private static final Prototype[] NOPROTOS = {};
|
private static final Prototype[] NOPROTOS = {};
|
||||||
private static final LocVars[] NOLOCVARS = {};
|
private static final LocVars[] NOLOCVARS = {};
|
||||||
|
private static final LuaString[] NOSTRVALUES = {};
|
||||||
private static final Upvaldesc[] NOUPVALDESCS = {};
|
private static final Upvaldesc[] NOUPVALDESCS = {};
|
||||||
private static final int[] NOINTS = {};
|
private static final int[] NOINTS = {};
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ public class Lua {
|
|||||||
public static final int POS_Bx = POS_C;
|
public static final int POS_Bx = POS_C;
|
||||||
public static final int POS_Ax = POS_A;
|
public static final int POS_Ax = POS_A;
|
||||||
|
|
||||||
|
|
||||||
public static final int MAX_OP = ((1<<SIZE_OP)-1);
|
public static final int MAX_OP = ((1<<SIZE_OP)-1);
|
||||||
public static final int MAXARG_A = ((1<<SIZE_A)-1);
|
public static final int MAXARG_A = ((1<<SIZE_A)-1);
|
||||||
public static final int MAXARG_B = ((1<<SIZE_B)-1);
|
public static final int MAXARG_B = ((1<<SIZE_B)-1);
|
||||||
@@ -93,7 +94,6 @@ public class Lua {
|
|||||||
public static final int MASK_B = ((1<<SIZE_B)-1)<<POS_B;
|
public static final int MASK_B = ((1<<SIZE_B)-1)<<POS_B;
|
||||||
public static final int MASK_C = ((1<<SIZE_C)-1)<<POS_C;
|
public static final int MASK_C = ((1<<SIZE_C)-1)<<POS_C;
|
||||||
public static final int MASK_Bx = ((1<<SIZE_Bx)-1)<<POS_Bx;
|
public static final int MASK_Bx = ((1<<SIZE_Bx)-1)<<POS_Bx;
|
||||||
public static final int MASK_Ax = ((1<<SIZE_Ax)-1)<<POS_Ax;
|
|
||||||
|
|
||||||
public static final int MASK_NOT_OP = ~MASK_OP;
|
public static final int MASK_NOT_OP = ~MASK_OP;
|
||||||
public static final int MASK_NOT_A = ~MASK_A;
|
public static final int MASK_NOT_A = ~MASK_A;
|
||||||
@@ -208,7 +208,7 @@ public class Lua {
|
|||||||
|
|
||||||
public static final int OP_CONCAT = 22; /* A B C R(A) := R(B).. ... ..R(C) */
|
public static final int OP_CONCAT = 22; /* A B C R(A) := R(B).. ... ..R(C) */
|
||||||
|
|
||||||
public static final int OP_JMP = 23; /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
|
public static final int OP_JMP = 23; /* sBx pc+=sBx */
|
||||||
public static final int OP_EQ = 24; /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
public static final int OP_EQ = 24; /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
||||||
public static final int OP_LT = 25; /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
public static final int OP_LT = 25; /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
||||||
public static final int OP_LE = 26; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
public static final int OP_LE = 26; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
||||||
|
|||||||
@@ -21,8 +21,6 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.vm2;
|
package org.luaj.vm2;
|
||||||
|
|
||||||
import org.luaj.vm2.lib.DebugLib.CallFrame;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension of {@link LuaFunction} which executes lua bytecode.
|
* Extension of {@link LuaFunction} which executes lua bytecode.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -99,20 +97,15 @@ public class LuaClosure extends LuaFunction {
|
|||||||
*/
|
*/
|
||||||
public LuaClosure(Prototype p, LuaValue env) {
|
public LuaClosure(Prototype p, LuaValue env) {
|
||||||
this.p = p;
|
this.p = p;
|
||||||
this.initupvalue1(env);
|
|
||||||
globals = env instanceof Globals? (Globals) env: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initupvalue1(LuaValue env) {
|
|
||||||
if (p.upvalues == null || p.upvalues.length == 0)
|
if (p.upvalues == null || p.upvalues.length == 0)
|
||||||
this.upValues = NOUPVALUES;
|
this.upValues = NOUPVALUES;
|
||||||
else {
|
else {
|
||||||
this.upValues = new UpValue[p.upvalues.length];
|
this.upValues = new UpValue[p.upvalues.length];
|
||||||
this.upValues[0] = new UpValue(new LuaValue[] {env}, 0);
|
this.upValues[0] = new UpValue(new LuaValue[] {env}, 0);
|
||||||
}
|
}
|
||||||
|
globals = env instanceof Globals? (Globals) env: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isclosure() {
|
public boolean isclosure() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -125,24 +118,26 @@ public class LuaClosure extends LuaFunction {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LuaValue getmetatable() {
|
||||||
|
return s_metatable;
|
||||||
|
}
|
||||||
|
|
||||||
public String tojstring() {
|
public String tojstring() {
|
||||||
return "function: " + p.toString();
|
return "function: " + p.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private LuaValue[] getNewStack() {
|
|
||||||
int max = p.maxstacksize;
|
|
||||||
LuaValue[] stack = new LuaValue[max];
|
|
||||||
System.arraycopy(NILS, 0, stack, 0, max);
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final LuaValue call() {
|
public final LuaValue call() {
|
||||||
LuaValue[] stack = getNewStack();
|
LuaValue[] stack = new LuaValue[p.maxstacksize];
|
||||||
|
for (int i = 0; i < p.numparams; ++i )
|
||||||
|
stack[i] = NIL;
|
||||||
return execute(stack,NONE).arg1();
|
return execute(stack,NONE).arg1();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final LuaValue call(LuaValue arg) {
|
public final LuaValue call(LuaValue arg) {
|
||||||
LuaValue[] stack = getNewStack();
|
LuaValue[] stack = new LuaValue[p.maxstacksize];
|
||||||
|
System.arraycopy(NILS, 0, stack, 0, p.maxstacksize);
|
||||||
|
for (int i = 1; i < p.numparams; ++i )
|
||||||
|
stack[i] = NIL;
|
||||||
switch ( p.numparams ) {
|
switch ( p.numparams ) {
|
||||||
default: stack[0]=arg; return execute(stack,NONE).arg1();
|
default: stack[0]=arg; return execute(stack,NONE).arg1();
|
||||||
case 0: return execute(stack,arg).arg1();
|
case 0: return execute(stack,arg).arg1();
|
||||||
@@ -150,7 +145,9 @@ public class LuaClosure extends LuaFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final LuaValue call(LuaValue arg1, LuaValue arg2) {
|
public final LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||||
LuaValue[] stack = getNewStack();
|
LuaValue[] stack = new LuaValue[p.maxstacksize];
|
||||||
|
for (int i = 2; i < p.numparams; ++i )
|
||||||
|
stack[i] = NIL;
|
||||||
switch ( p.numparams ) {
|
switch ( p.numparams ) {
|
||||||
default: stack[0]=arg1; stack[1]=arg2; return execute(stack,NONE).arg1();
|
default: stack[0]=arg1; stack[1]=arg2; return execute(stack,NONE).arg1();
|
||||||
case 1: stack[0]=arg1; return execute(stack,arg2).arg1();
|
case 1: stack[0]=arg1; return execute(stack,arg2).arg1();
|
||||||
@@ -159,7 +156,9 @@ public class LuaClosure extends LuaFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
|
public final LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
|
||||||
LuaValue[] stack = getNewStack();
|
LuaValue[] stack = new LuaValue[p.maxstacksize];
|
||||||
|
for (int i = 3; i < p.numparams; ++i )
|
||||||
|
stack[i] = NIL;
|
||||||
switch ( p.numparams ) {
|
switch ( p.numparams ) {
|
||||||
default: stack[0]=arg1; stack[1]=arg2; stack[2]=arg3; return execute(stack,NONE).arg1();
|
default: stack[0]=arg1; stack[1]=arg2; stack[2]=arg3; return execute(stack,NONE).arg1();
|
||||||
case 2: stack[0]=arg1; stack[1]=arg2; return execute(stack,arg3).arg1();
|
case 2: stack[0]=arg1; stack[1]=arg2; return execute(stack,arg3).arg1();
|
||||||
@@ -173,7 +172,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final Varargs onInvoke(Varargs varargs) {
|
public final Varargs onInvoke(Varargs varargs) {
|
||||||
LuaValue[] stack = getNewStack();
|
LuaValue[] stack = new LuaValue[p.maxstacksize];
|
||||||
for ( int i=0; i<p.numparams; i++ )
|
for ( int i=0; i<p.numparams; i++ )
|
||||||
stack[i] = varargs.arg(i+1);
|
stack[i] = varargs.arg(i+1);
|
||||||
return execute(stack,p.is_vararg!=0? varargs.subargs(p.numparams+1): NONE);
|
return execute(stack,p.is_vararg!=0? varargs.subargs(p.numparams+1): NONE);
|
||||||
@@ -216,17 +215,6 @@ public class LuaClosure extends LuaFunction {
|
|||||||
stack[a] = k[i>>>14];
|
stack[a] = k[i>>>14];
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_LOADKX:/* A R(A) := Kst(extra arg) */
|
|
||||||
++pc;
|
|
||||||
i = code[pc];
|
|
||||||
if ((i & 0x3f) != Lua.OP_EXTRAARG) {
|
|
||||||
int op = i & 0x3f;
|
|
||||||
throw new LuaError("OP_EXTRAARG expected after OP_LOADKX, got " +
|
|
||||||
(op < Print.OPNAMES.length - 1 ? Print.OPNAMES[op] : "UNKNOWN_OP_" + op));
|
|
||||||
}
|
|
||||||
stack[a] = k[i>>>6];
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_LOADBOOL:/* A B C R(A):= (Bool)B: if (C) pc++ */
|
case Lua.OP_LOADBOOL:/* A B C R(A):= (Bool)B: if (C) pc++ */
|
||||||
stack[a] = (i>>>23!=0)? LuaValue.TRUE: LuaValue.FALSE;
|
stack[a] = (i>>>23!=0)? LuaValue.TRUE: LuaValue.FALSE;
|
||||||
if ((i&(0x1ff<<14)) != 0)
|
if ((i&(0x1ff<<14)) != 0)
|
||||||
@@ -314,7 +302,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
if ( c > b+1 ) {
|
if ( c > b+1 ) {
|
||||||
Buffer sb = stack[c].buffer();
|
Buffer sb = stack[c].buffer();
|
||||||
while ( --c>=b )
|
while ( --c>=b )
|
||||||
sb.concatTo(stack[c]);
|
sb = stack[c].concat(sb);
|
||||||
stack[a] = sb.value();
|
stack[a] = sb.value();
|
||||||
} else {
|
} else {
|
||||||
stack[a] = stack[c-1].concat(stack[c]);
|
stack[a] = stack[c-1].concat(stack[c]);
|
||||||
@@ -322,7 +310,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lua.OP_JMP: /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
|
case Lua.OP_JMP: /* sBx pc+=sBx */
|
||||||
pc += (i>>>14)-0x1ffff;
|
pc += (i>>>14)-0x1ffff;
|
||||||
if (a > 0) {
|
if (a > 0) {
|
||||||
for (--a, b = openups.length; --b>=0; )
|
for (--a, b = openups.length; --b>=0; )
|
||||||
@@ -417,7 +405,7 @@ public class LuaClosure extends LuaFunction {
|
|||||||
{
|
{
|
||||||
LuaValue limit = stack[a + 1];
|
LuaValue limit = stack[a + 1];
|
||||||
LuaValue step = stack[a + 2];
|
LuaValue step = stack[a + 2];
|
||||||
LuaValue idx = stack[a].add(step);
|
LuaValue idx = step.add(stack[a]);
|
||||||
if (step.gt_b(0)? idx.lteq_b(limit): idx.gteq_b(limit)) {
|
if (step.gt_b(0)? idx.lteq_b(limit): idx.gteq_b(limit)) {
|
||||||
stack[a] = idx;
|
stack[a] = idx;
|
||||||
stack[a + 3] = idx;
|
stack[a + 3] = idx;
|
||||||
@@ -549,24 +537,8 @@ public class LuaClosure extends LuaFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void processErrorHooks(LuaError le, Prototype p, int pc) {
|
private void processErrorHooks(LuaError le, Prototype p, int pc) {
|
||||||
String file = "?";
|
le.fileline = (p.source != null? p.source.tojstring(): "?") + ":"
|
||||||
int line = -1;
|
+ (p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length? String.valueOf(p.lineinfo[pc]): "?");
|
||||||
{
|
|
||||||
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);
|
le.traceback = errorHook(le.getMessage(), le.level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -177,14 +177,7 @@ public class LuaDouble extends LuaNumber {
|
|||||||
* @see #dmod_d(double, double)
|
* @see #dmod_d(double, double)
|
||||||
*/
|
*/
|
||||||
public static LuaValue dmod(double lhs, double rhs) {
|
public static LuaValue dmod(double lhs, double rhs) {
|
||||||
if (rhs == 0 || lhs == Double.POSITIVE_INFINITY || lhs == Double.NEGATIVE_INFINITY) return NAN;
|
return rhs!=0? valueOf( lhs-rhs*Math.floor(lhs/rhs) ): 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.
|
/** Take modulo for double numbers according to lua math, and return a double result.
|
||||||
@@ -195,39 +188,32 @@ public class LuaDouble extends LuaNumber {
|
|||||||
* @see #dmod(double, double)
|
* @see #dmod(double, double)
|
||||||
*/
|
*/
|
||||||
public static double dmod_d(double lhs, double rhs) {
|
public static double dmod_d(double lhs, double rhs) {
|
||||||
if (rhs == 0 || lhs == Double.POSITIVE_INFINITY || lhs == Double.NEGATIVE_INFINITY) return Double.NaN;
|
return rhs!=0? lhs-rhs*Math.floor(lhs/rhs): 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
|
// relational operators
|
||||||
public LuaValue lt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gt_b(v)? TRUE: FALSE) : super.lt(rhs); }
|
public LuaValue lt( LuaValue rhs ) { return rhs.gt_b(v)? LuaValue.TRUE: FALSE; }
|
||||||
public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; }
|
public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; }
|
||||||
public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; }
|
public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; }
|
||||||
public boolean lt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gt_b(v) : super.lt_b(rhs); }
|
public boolean lt_b( LuaValue rhs ) { return rhs.gt_b(v); }
|
||||||
public boolean lt_b( int rhs ) { return v < rhs; }
|
public boolean lt_b( int rhs ) { return v < rhs; }
|
||||||
public boolean lt_b( double rhs ) { return v < rhs; }
|
public boolean lt_b( double rhs ) { return v < rhs; }
|
||||||
public LuaValue lteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gteq_b(v)? TRUE: FALSE) : super.lteq(rhs); }
|
public LuaValue lteq( LuaValue rhs ) { return rhs.gteq_b(v)? LuaValue.TRUE: FALSE; }
|
||||||
public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; }
|
public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; }
|
||||||
public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; }
|
public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; }
|
||||||
public boolean lteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gteq_b(v) : super.lteq_b(rhs); }
|
public boolean lteq_b( LuaValue rhs ) { return rhs.gteq_b(v); }
|
||||||
public boolean lteq_b( int rhs ) { return v <= rhs; }
|
public boolean lteq_b( int rhs ) { return v <= rhs; }
|
||||||
public boolean lteq_b( double rhs ) { return v <= rhs; }
|
public boolean lteq_b( double rhs ) { return v <= rhs; }
|
||||||
public LuaValue gt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lt_b(v)? TRUE: FALSE) : super.gt(rhs); }
|
public LuaValue gt( LuaValue rhs ) { return rhs.lt_b(v)? LuaValue.TRUE: FALSE; }
|
||||||
public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; }
|
public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; }
|
||||||
public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; }
|
public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; }
|
||||||
public boolean gt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lt_b(v) : super.gt_b(rhs); }
|
public boolean gt_b( LuaValue rhs ) { return rhs.lt_b(v); }
|
||||||
public boolean gt_b( int rhs ) { return v > rhs; }
|
public boolean gt_b( int rhs ) { return v > rhs; }
|
||||||
public boolean gt_b( double rhs ) { return v > rhs; }
|
public boolean gt_b( double rhs ) { return v > rhs; }
|
||||||
public LuaValue gteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lteq_b(v)? TRUE: FALSE) : super.gteq(rhs); }
|
public LuaValue gteq( LuaValue rhs ) { return rhs.lteq_b(v)? LuaValue.TRUE: FALSE; }
|
||||||
public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; }
|
public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; }
|
||||||
public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; }
|
public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; }
|
||||||
public boolean gteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lteq_b(v) : super.gteq_b(rhs); }
|
public boolean gteq_b( LuaValue rhs ) { return rhs.lteq_b(v); }
|
||||||
public boolean gteq_b( int rhs ) { return v >= rhs; }
|
public boolean gteq_b( int rhs ) { return v >= rhs; }
|
||||||
public boolean gteq_b( double rhs ) { return v >= rhs; }
|
public boolean gteq_b( double rhs ) { return v >= rhs; }
|
||||||
|
|
||||||
|
|||||||
@@ -74,13 +74,10 @@ public class LuaFunction extends LuaValue {
|
|||||||
|
|
||||||
/** 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 ($).
|
* @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() {
|
public String classnamestub() {
|
||||||
String s = getClass().getName();
|
String s = getClass().getName();
|
||||||
int offset = Math.max(s.lastIndexOf('.'), s.lastIndexOf('$')) + 1;
|
return s.substring(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.
|
/** Return a human-readable name for this function. Returns the last part of the class name by default.
|
||||||
|
|||||||
@@ -172,28 +172,28 @@ public class LuaInteger extends LuaNumber {
|
|||||||
public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs,v); }
|
public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs,v); }
|
||||||
|
|
||||||
// relational operators
|
// relational operators
|
||||||
public LuaValue lt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gt_b(v)? TRUE: FALSE) : super.lt(rhs); }
|
public LuaValue lt( LuaValue rhs ) { return rhs.gt_b(v)? TRUE: FALSE; }
|
||||||
public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; }
|
public LuaValue lt( double rhs ) { return v < rhs? TRUE: FALSE; }
|
||||||
public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; }
|
public LuaValue lt( int rhs ) { return v < rhs? TRUE: FALSE; }
|
||||||
public boolean lt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gt_b(v) : super.lt_b(rhs); }
|
public boolean lt_b( LuaValue rhs ) { return rhs.gt_b(v); }
|
||||||
public boolean lt_b( int rhs ) { return v < rhs; }
|
public boolean lt_b( int rhs ) { return v < rhs; }
|
||||||
public boolean lt_b( double rhs ) { return v < rhs; }
|
public boolean lt_b( double rhs ) { return v < rhs; }
|
||||||
public LuaValue lteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.gteq_b(v)? TRUE: FALSE) : super.lteq(rhs); }
|
public LuaValue lteq( LuaValue rhs ) { return rhs.gteq_b(v)? TRUE: FALSE; }
|
||||||
public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; }
|
public LuaValue lteq( double rhs ) { return v <= rhs? TRUE: FALSE; }
|
||||||
public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; }
|
public LuaValue lteq( int rhs ) { return v <= rhs? TRUE: FALSE; }
|
||||||
public boolean lteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.gteq_b(v) : super.lteq_b(rhs); }
|
public boolean lteq_b( LuaValue rhs ) { return rhs.gteq_b(v); }
|
||||||
public boolean lteq_b( int rhs ) { return v <= rhs; }
|
public boolean lteq_b( int rhs ) { return v <= rhs; }
|
||||||
public boolean lteq_b( double rhs ) { return v <= rhs; }
|
public boolean lteq_b( double rhs ) { return v <= rhs; }
|
||||||
public LuaValue gt( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lt_b(v)? TRUE: FALSE) : super.gt(rhs); }
|
public LuaValue gt( LuaValue rhs ) { return rhs.lt_b(v)? TRUE: FALSE; }
|
||||||
public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; }
|
public LuaValue gt( double rhs ) { return v > rhs? TRUE: FALSE; }
|
||||||
public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; }
|
public LuaValue gt( int rhs ) { return v > rhs? TRUE: FALSE; }
|
||||||
public boolean gt_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lt_b(v) : super.gt_b(rhs); }
|
public boolean gt_b( LuaValue rhs ) { return rhs.lt_b(v); }
|
||||||
public boolean gt_b( int rhs ) { return v > rhs; }
|
public boolean gt_b( int rhs ) { return v > rhs; }
|
||||||
public boolean gt_b( double rhs ) { return v > rhs; }
|
public boolean gt_b( double rhs ) { return v > rhs; }
|
||||||
public LuaValue gteq( LuaValue rhs ) { return rhs instanceof LuaNumber ? (rhs.lteq_b(v)? TRUE: FALSE) : super.gteq(rhs); }
|
public LuaValue gteq( LuaValue rhs ) { return rhs.lteq_b(v)? TRUE: FALSE; }
|
||||||
public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; }
|
public LuaValue gteq( double rhs ) { return v >= rhs? TRUE: FALSE; }
|
||||||
public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; }
|
public LuaValue gteq( int rhs ) { return v >= rhs? TRUE: FALSE; }
|
||||||
public boolean gteq_b( LuaValue rhs ) { return rhs instanceof LuaNumber ? rhs.lteq_b(v) : super.gteq_b(rhs); }
|
public boolean gteq_b( LuaValue rhs ) { return rhs.lteq_b(v); }
|
||||||
public boolean gteq_b( int rhs ) { return v >= rhs; }
|
public boolean gteq_b( int rhs ) { return v >= rhs; }
|
||||||
public boolean gteq_b( double rhs ) { return v >= rhs; }
|
public boolean gteq_b( double rhs ) { return v >= rhs; }
|
||||||
|
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ public class LuaString extends LuaValue {
|
|||||||
/** Construct a new LuaString using a copy of the bytes array supplied */
|
/** Construct a new LuaString using a copy of the bytes array supplied */
|
||||||
private static LuaString valueFromCopy(byte[] bytes, int off, int len) {
|
private static LuaString valueFromCopy(byte[] bytes, int off, int len) {
|
||||||
final byte[] copy = new byte[len];
|
final byte[] copy = new byte[len];
|
||||||
System.arraycopy(bytes, off, copy, 0, len);
|
for (int i=0; i<len; ++i) copy[i] = bytes[off+i];
|
||||||
return new LuaString(copy, 0, len);
|
return new LuaString(copy, 0, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,20 +289,20 @@ public class LuaString extends LuaValue {
|
|||||||
public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs, checkarith()); }
|
public LuaValue modFrom( double lhs ) { return LuaDouble.dmod(lhs, checkarith()); }
|
||||||
|
|
||||||
// relational operators, these only work with other strings
|
// relational operators, these only work with other strings
|
||||||
public LuaValue lt( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)>0? LuaValue.TRUE: FALSE) : super.lt(rhs); }
|
public LuaValue lt( LuaValue rhs ) { return rhs.strcmp(this)>0? LuaValue.TRUE: FALSE; }
|
||||||
public boolean lt_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)>0 : super.lt_b(rhs); }
|
public boolean lt_b( LuaValue rhs ) { return rhs.strcmp(this)>0; }
|
||||||
public boolean lt_b( int rhs ) { typerror("attempt to compare string with number"); return false; }
|
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 boolean lt_b( double rhs ) { typerror("attempt to compare string with number"); return false; }
|
||||||
public LuaValue lteq( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)>=0? LuaValue.TRUE: FALSE) : super.lteq(rhs); }
|
public LuaValue lteq( LuaValue rhs ) { return rhs.strcmp(this)>=0? LuaValue.TRUE: FALSE; }
|
||||||
public boolean lteq_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)>=0 : super.lteq_b(rhs); }
|
public boolean lteq_b( LuaValue rhs ) { return rhs.strcmp(this)>=0; }
|
||||||
public boolean lteq_b( int rhs ) { typerror("attempt to compare string with number"); return false; }
|
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 boolean lteq_b( double rhs ) { typerror("attempt to compare string with number"); return false; }
|
||||||
public LuaValue gt( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)<0? LuaValue.TRUE: FALSE) : super.gt(rhs); }
|
public LuaValue gt( LuaValue rhs ) { return rhs.strcmp(this)<0? LuaValue.TRUE: FALSE; }
|
||||||
public boolean gt_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)<0 : super.gt_b(rhs); }
|
public boolean gt_b( LuaValue rhs ) { return rhs.strcmp(this)<0; }
|
||||||
public boolean gt_b( int rhs ) { typerror("attempt to compare string with number"); return false; }
|
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 boolean gt_b( double rhs ) { typerror("attempt to compare string with number"); return false; }
|
||||||
public LuaValue gteq( LuaValue rhs ) { return rhs.isstring() ? (rhs.strcmp(this)<=0? LuaValue.TRUE: FALSE) : super.gteq(rhs); }
|
public LuaValue gteq( LuaValue rhs ) { return rhs.strcmp(this)<=0? LuaValue.TRUE: FALSE; }
|
||||||
public boolean gteq_b( LuaValue rhs ) { return rhs.isstring() ? rhs.strcmp(this)<=0 : super.gteq_b(rhs); }
|
public boolean gteq_b( LuaValue rhs ) { return rhs.strcmp(this)<=0; }
|
||||||
public boolean gteq_b( int rhs ) { typerror("attempt to compare string with number"); return false; }
|
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; }
|
public boolean gteq_b( double rhs ) { typerror("attempt to compare string with number"); return false; }
|
||||||
|
|
||||||
@@ -391,23 +391,23 @@ public class LuaString extends LuaValue {
|
|||||||
public short toshort() { return (short) toint(); }
|
public short toshort() { return (short) toint(); }
|
||||||
|
|
||||||
public double optdouble(double defval) {
|
public double optdouble(double defval) {
|
||||||
return checkdouble();
|
return checknumber().checkdouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int optint(int defval) {
|
public int optint(int defval) {
|
||||||
return checkint();
|
return checknumber().checkint();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaInteger optinteger(LuaInteger defval) {
|
public LuaInteger optinteger(LuaInteger defval) {
|
||||||
return checkinteger();
|
return checknumber().checkinteger();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long optlong(long defval) {
|
public long optlong(long defval) {
|
||||||
return checklong();
|
return checknumber().checklong();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaNumber optnumber(LuaNumber defval) {
|
public LuaNumber optnumber(LuaNumber defval) {
|
||||||
return checknumber();
|
return checknumber().checknumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaString optstring(LuaString defval) {
|
public LuaString optstring(LuaString defval) {
|
||||||
|
|||||||
@@ -266,8 +266,8 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
|
|
||||||
/** caller must ensure key is not nil */
|
/** caller must ensure key is not nil */
|
||||||
public void set( LuaValue key, LuaValue value ) {
|
public void set( LuaValue key, LuaValue value ) {
|
||||||
if (key == null || !key.isvalidkey() && !metatag(NEWINDEX).isfunction())
|
if (!key.isvalidkey() && !metatag(NEWINDEX).isfunction())
|
||||||
throw new LuaError("value ('" + key + "') can not be used as a table index");
|
typerror("table index");
|
||||||
if ( m_metatable==null || ! rawget(key).isnil() || ! settable(this,key,value) )
|
if ( m_metatable==null || ! rawget(key).isnil() || ! settable(this,key,value) )
|
||||||
rawset(key, value);
|
rawset(key, value);
|
||||||
}
|
}
|
||||||
@@ -299,15 +299,15 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
* @return The removed item, or {@link #NONE} if not removed
|
* @return The removed item, or {@link #NONE} if not removed
|
||||||
*/
|
*/
|
||||||
public LuaValue remove(int pos) {
|
public LuaValue remove(int pos) {
|
||||||
int n = length();
|
int n = rawlen();
|
||||||
if ( pos == 0 )
|
if ( pos == 0 )
|
||||||
pos = n;
|
pos = n;
|
||||||
else if (pos > n)
|
else if (pos > n)
|
||||||
return NONE;
|
return NONE;
|
||||||
LuaValue v = get(pos);
|
LuaValue v = rawget(pos);
|
||||||
for ( LuaValue r=v; !r.isnil(); ) {
|
for ( LuaValue r=v; !r.isnil(); ) {
|
||||||
r = get(pos+1);
|
r = rawget(pos+1);
|
||||||
set(pos++, r);
|
rawset(pos++, r);
|
||||||
}
|
}
|
||||||
return v.isnil()? NONE: v;
|
return v.isnil()? NONE: v;
|
||||||
}
|
}
|
||||||
@@ -319,10 +319,10 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
*/
|
*/
|
||||||
public void insert(int pos, LuaValue value) {
|
public void insert(int pos, LuaValue value) {
|
||||||
if ( pos == 0 )
|
if ( pos == 0 )
|
||||||
pos = length()+1;
|
pos = rawlen()+1;
|
||||||
while ( ! value.isnil() ) {
|
while ( ! value.isnil() ) {
|
||||||
LuaValue v = get( pos );
|
LuaValue v = rawget( pos );
|
||||||
set(pos++, value);
|
rawset(pos++, value);
|
||||||
value = v;
|
value = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -347,12 +347,7 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int length() {
|
public int length() {
|
||||||
if (m_metatable != null) {
|
return m_metatable != null? len().toint(): rawlen();
|
||||||
LuaValue len = len();
|
|
||||||
if (!len.isint()) throw new LuaError("table length is not an integer: " + len);
|
|
||||||
return len.toint();
|
|
||||||
}
|
|
||||||
return rawlen();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LuaValue len() {
|
public LuaValue len() {
|
||||||
@@ -395,7 +390,7 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( hash.length == 0 )
|
if ( hash.length == 0 )
|
||||||
error( "invalid key to 'next' 1: " + key );
|
error( "invalid key to 'next'" );
|
||||||
i = hashSlot( key );
|
i = hashSlot( key );
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for ( Slot slot = hash[i]; slot != null; slot = slot.rest() ) {
|
for ( Slot slot = hash[i]; slot != null; slot = slot.rest() ) {
|
||||||
@@ -409,7 +404,7 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( !found ) {
|
if ( !found ) {
|
||||||
error( "invalid key to 'next' 2: " + key );
|
error( "invalid key to 'next'" );
|
||||||
}
|
}
|
||||||
i += 1+array.length;
|
i += 1+array.length;
|
||||||
}
|
}
|
||||||
@@ -472,8 +467,7 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( checkLoadFactor() ) {
|
if ( checkLoadFactor() ) {
|
||||||
if ( (m_metatable == null || !m_metatable.useWeakValues())
|
if ( key.isinttype() && key.toint() > 0 ) {
|
||||||
&& key.isinttype() && key.toint() > 0 ) {
|
|
||||||
// a rehash might make room in the array portion for this key.
|
// a rehash might make room in the array portion for this key.
|
||||||
rehash( key.toint() );
|
rehash( key.toint() );
|
||||||
if ( arrayset(key.toint(), value) )
|
if ( arrayset(key.toint(), value) )
|
||||||
@@ -720,7 +714,7 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
StrongSlot entry = slot.first();
|
StrongSlot entry = slot.first();
|
||||||
if (entry != null)
|
if (entry != null)
|
||||||
newArray[ k - 1 ] = entry.value();
|
newArray[ k - 1 ] = entry.value();
|
||||||
} else if ( !(slot instanceof DeadSlot) ) {
|
} else {
|
||||||
int j = slot.keyindex( newHashMask );
|
int j = slot.keyindex( newHashMask );
|
||||||
newHash[j] = slot.relink( newHash[j] );
|
newHash[j] = slot.relink( newHash[j] );
|
||||||
}
|
}
|
||||||
@@ -786,39 +780,36 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
* @param comparator {@link LuaValue} to be called to compare elements.
|
* @param comparator {@link LuaValue} to be called to compare elements.
|
||||||
*/
|
*/
|
||||||
public void sort(LuaValue comparator) {
|
public void sort(LuaValue comparator) {
|
||||||
if (len().tolong() >= (long)Integer.MAX_VALUE) throw new LuaError("array too big: " + len().tolong());
|
|
||||||
if (m_metatable != null && m_metatable.useWeakValues()) {
|
if (m_metatable != null && m_metatable.useWeakValues()) {
|
||||||
dropWeakArrayValues();
|
dropWeakArrayValues();
|
||||||
}
|
}
|
||||||
int n = length();
|
int n = array.length;
|
||||||
|
while ( n > 0 && array[n-1] == null )
|
||||||
|
--n;
|
||||||
if ( n > 1 )
|
if ( n > 1 )
|
||||||
heapSort(n, comparator.isnil() ? null : comparator);
|
heapSort(n, comparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void heapSort(int count, LuaValue cmpfunc) {
|
private void heapSort(int count, LuaValue cmpfunc) {
|
||||||
heapify(count, cmpfunc);
|
heapify(count, cmpfunc);
|
||||||
for ( int end=count; end>1; ) {
|
for ( int end=count-1; end>0; ) {
|
||||||
LuaValue a = get(end); // swap(end, 1)
|
swap(end, 0);
|
||||||
set(end, get(1));
|
siftDown(0, --end, cmpfunc);
|
||||||
set(1, a);
|
|
||||||
siftDown(1, --end, cmpfunc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void heapify(int count, LuaValue cmpfunc) {
|
private void heapify(int count, LuaValue cmpfunc) {
|
||||||
for ( int start=count/2; start>0; --start )
|
for ( int start=count/2-1; start>=0; --start )
|
||||||
siftDown(start, count, cmpfunc);
|
siftDown(start, count - 1, cmpfunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void siftDown(int start, int end, LuaValue cmpfunc) {
|
private void siftDown(int start, int end, LuaValue cmpfunc) {
|
||||||
for ( int root=start; root*2 <= end; ) {
|
for ( int root=start; root*2+1 <= end; ) {
|
||||||
int child = root*2;
|
int child = root*2+1;
|
||||||
if (child < end && compare(child, child + 1, cmpfunc))
|
if (child < end && compare(child, child + 1, cmpfunc))
|
||||||
++child;
|
++child;
|
||||||
if (compare(root, child, cmpfunc)) {
|
if (compare(root, child, cmpfunc)) {
|
||||||
LuaValue a = get(root); // swap(root, child)
|
swap(root, child);
|
||||||
set(root, get(child));
|
|
||||||
set(child, a);
|
|
||||||
root = child;
|
root = child;
|
||||||
} else
|
} else
|
||||||
return;
|
return;
|
||||||
@@ -826,16 +817,29 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean compare(int i, int j, LuaValue cmpfunc) {
|
private boolean compare(int i, int j, LuaValue cmpfunc) {
|
||||||
LuaValue a = get(i), b = get(j);
|
LuaValue a, b;
|
||||||
|
if (m_metatable == null) {
|
||||||
|
a = array[i];
|
||||||
|
b = array[j];
|
||||||
|
} else {
|
||||||
|
a = m_metatable.arrayget(array, i);
|
||||||
|
b = m_metatable.arrayget(array, j);
|
||||||
|
}
|
||||||
if ( a == null || b == null )
|
if ( a == null || b == null )
|
||||||
return false;
|
return false;
|
||||||
if ( cmpfunc != null ) {
|
if ( ! cmpfunc.isnil() ) {
|
||||||
return cmpfunc.call(a,b).toboolean();
|
return cmpfunc.call(a,b).toboolean();
|
||||||
} else {
|
} else {
|
||||||
return a.lt_b(b);
|
return a.lt_b(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void swap(int i, int j) {
|
||||||
|
LuaValue a = array[i];
|
||||||
|
array[i] = array[j];
|
||||||
|
array[j] = a;
|
||||||
|
}
|
||||||
|
|
||||||
/** This may be deprecated in a future release.
|
/** 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
|
* @return count of keys in the table
|
||||||
@@ -888,11 +892,6 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
|
|
||||||
/** Unpack the elements from i to j inclusive */
|
/** Unpack the elements from i to j inclusive */
|
||||||
public Varargs unpack(int i, int j) {
|
public Varargs unpack(int i, int j) {
|
||||||
if (j < i) return NONE;
|
|
||||||
int count = j - i;
|
|
||||||
if (count < 0) throw new LuaError("too many results to unpack: greater " + Integer.MAX_VALUE); // integer overflow
|
|
||||||
int max = 0x00ffffff;
|
|
||||||
if (count >= max) throw new LuaError("too many results to unpack: " + count + " (max is " + max + ')');
|
|
||||||
int n = j + 1 - i;
|
int n = j + 1 - i;
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 0: return NONE;
|
case 0: return NONE;
|
||||||
@@ -901,14 +900,10 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
default:
|
default:
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
return NONE;
|
return NONE;
|
||||||
try {
|
|
||||||
LuaValue[] v = new LuaValue[n];
|
LuaValue[] v = new LuaValue[n];
|
||||||
while (--n >= 0)
|
while (--n >= 0)
|
||||||
v[n] = get(i+n);
|
v[n] = get(i+n);
|
||||||
return varargsOf(v);
|
return varargsOf(v);
|
||||||
} catch (OutOfMemoryError e) {
|
|
||||||
throw new LuaError("too many results to unpack [out of memory]: " + n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1236,15 +1231,14 @@ public class LuaTable extends LuaValue implements Metatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Entry set(LuaValue value) {
|
public Entry set(LuaValue value) {
|
||||||
if (value.type() == TNUMBER) {
|
|
||||||
LuaValue n = value.tonumber();
|
LuaValue n = value.tonumber();
|
||||||
if (!n.isnil()) {
|
if ( !n.isnil() ) {
|
||||||
this.value = n.todouble();
|
this.value = n.todouble();
|
||||||
return this;
|
return this;
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
return new NormalEntry( this.key, value );
|
return new NormalEntry( this.key, value );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int keyindex( int mask ) {
|
public int keyindex( int mask ) {
|
||||||
return hashSlot( key, mask );
|
return hashSlot( key, mask );
|
||||||
|
|||||||
@@ -23,10 +23,6 @@ package org.luaj.vm2;
|
|||||||
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.locks.Condition;
|
|
||||||
import java.util.concurrent.locks.Lock;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subclass of {@link LuaValue} that implements
|
* Subclass of {@link LuaValue} that implements
|
||||||
@@ -86,19 +82,6 @@ public class LuaThread extends LuaValue {
|
|||||||
*/
|
*/
|
||||||
public static long thread_orphan_check_interval = 5000;
|
public static long thread_orphan_check_interval = 5000;
|
||||||
|
|
||||||
public static final String USE_PLATFORM_THREAD = "USE_PLATFORM_THREAD";
|
|
||||||
|
|
||||||
private static boolean SUPPORT_VIRTUAL_THREAD = false;
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
Thread.class.getMethod("ofVirtual");
|
|
||||||
SUPPORT_VIRTUAL_THREAD = true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
//e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final int STATUS_INITIAL = 0;
|
public static final int STATUS_INITIAL = 0;
|
||||||
public static final int STATUS_SUSPENDED = 1;
|
public static final int STATUS_SUSPENDED = 1;
|
||||||
public static final int STATUS_RUNNING = 2;
|
public static final int STATUS_RUNNING = 2;
|
||||||
@@ -201,8 +184,6 @@ public class LuaThread extends LuaValue {
|
|||||||
public int bytecodes;
|
public int bytecodes;
|
||||||
|
|
||||||
public int status = LuaThread.STATUS_INITIAL;
|
public int status = LuaThread.STATUS_INITIAL;
|
||||||
private Lock locker = new ReentrantLock();
|
|
||||||
private Condition cond = locker.newCondition();
|
|
||||||
|
|
||||||
State(Globals globals, LuaThread lua_thread, LuaValue function) {
|
State(Globals globals, LuaThread lua_thread, LuaValue function) {
|
||||||
this.globals = globals;
|
this.globals = globals;
|
||||||
@@ -210,9 +191,7 @@ public class LuaThread extends LuaValue {
|
|||||||
this.function = function;
|
this.function = function;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public synchronized void run() {
|
||||||
locker.lock();
|
|
||||||
try {
|
|
||||||
try {
|
try {
|
||||||
Varargs a = this.args;
|
Varargs a = this.args;
|
||||||
this.args = LuaValue.NONE;
|
this.args = LuaValue.NONE;
|
||||||
@@ -221,45 +200,25 @@ public class LuaThread extends LuaValue {
|
|||||||
this.error = t.getMessage();
|
this.error = t.getMessage();
|
||||||
} finally {
|
} finally {
|
||||||
this.status = LuaThread.STATUS_DEAD;
|
this.status = LuaThread.STATUS_DEAD;
|
||||||
cond.signal();
|
this.notify();
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
locker.unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Varargs lua_resume(LuaThread new_thread, Varargs args) {
|
public synchronized Varargs lua_resume(LuaThread new_thread, Varargs args) {
|
||||||
locker.lock();
|
|
||||||
try {
|
|
||||||
LuaThread previous_thread = globals.running;
|
LuaThread previous_thread = globals.running;
|
||||||
try {
|
try {
|
||||||
globals.running = new_thread;
|
globals.running = new_thread;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
if (this.status == STATUS_INITIAL) {
|
if (this.status == STATUS_INITIAL) {
|
||||||
this.status = STATUS_RUNNING;
|
this.status = STATUS_RUNNING;
|
||||||
Thread t = null;
|
|
||||||
if(SUPPORT_VIRTUAL_THREAD) {
|
|
||||||
LuaValue setting = globals.get(USE_PLATFORM_THREAD);
|
|
||||||
if(setting.isnil()) {//default
|
|
||||||
if(Thread.currentThread().isVirtual()) {
|
|
||||||
t = Thread.ofVirtual().name("Coroutine-"+(++coroutine_count)).start(this);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(!setting.toboolean()) {
|
|
||||||
t = Thread.ofVirtual().name("Coroutine-"+(++coroutine_count)).start(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (t == null){
|
|
||||||
new Thread(this, "Coroutine-"+(++coroutine_count)).start();
|
new Thread(this, "Coroutine-"+(++coroutine_count)).start();
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
cond.signal();
|
this.notify();
|
||||||
}
|
}
|
||||||
if (previous_thread != null)
|
if (previous_thread != null)
|
||||||
previous_thread.state.status = STATUS_NORMAL;
|
previous_thread.state.status = STATUS_NORMAL;
|
||||||
this.status = STATUS_RUNNING;
|
this.status = STATUS_RUNNING;
|
||||||
cond.await();
|
this.wait();
|
||||||
return (this.error != null?
|
return (this.error != null?
|
||||||
LuaValue.varargsOf(LuaValue.FALSE, LuaValue.valueOf(this.error)):
|
LuaValue.varargsOf(LuaValue.FALSE, LuaValue.valueOf(this.error)):
|
||||||
LuaValue.varargsOf(LuaValue.TRUE, this.result));
|
LuaValue.varargsOf(LuaValue.TRUE, this.result));
|
||||||
@@ -273,20 +232,15 @@ public class LuaThread extends LuaValue {
|
|||||||
if (previous_thread != null)
|
if (previous_thread != null)
|
||||||
globals.running.state.status =STATUS_RUNNING;
|
globals.running.state.status =STATUS_RUNNING;
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
locker.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Varargs lua_yield(Varargs args) {
|
public synchronized Varargs lua_yield(Varargs args) {
|
||||||
locker.lock();
|
|
||||||
try {
|
|
||||||
try {
|
try {
|
||||||
this.result = args;
|
this.result = args;
|
||||||
this.status = STATUS_SUSPENDED;
|
this.status = STATUS_SUSPENDED;
|
||||||
cond.signal();
|
this.notify();
|
||||||
do {
|
do {
|
||||||
cond.await(thread_orphan_check_interval,TimeUnit.MILLISECONDS);
|
this.wait(thread_orphan_check_interval);
|
||||||
if (this.lua_thread.get() == null) {
|
if (this.lua_thread.get() == null) {
|
||||||
this.status = STATUS_DEAD;
|
this.status = STATUS_DEAD;
|
||||||
throw new OrphanedThread();
|
throw new OrphanedThread();
|
||||||
@@ -300,9 +254,6 @@ public class LuaThread extends LuaValue {
|
|||||||
this.args = LuaValue.NONE;
|
this.args = LuaValue.NONE;
|
||||||
this.result = LuaValue.NONE;
|
this.result = LuaValue.NONE;
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
locker.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.vm2;
|
package org.luaj.vm2;
|
||||||
|
|
||||||
|
import org.luaj.vm2.Varargs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all concrete lua type values.
|
* Base class for all concrete lua type values.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -641,7 +643,7 @@ public class LuaValue extends Varargs {
|
|||||||
* @see #isnumber()
|
* @see #isnumber()
|
||||||
* @see #TNUMBER
|
* @see #TNUMBER
|
||||||
*/
|
*/
|
||||||
public double optdouble(double defval) { argerror("number"); return 0; }
|
public double optdouble(double defval) { argerror("double"); return 0; }
|
||||||
|
|
||||||
/** Check that optional argument is a function and return as {@link LuaFunction}
|
/** Check that optional argument is a function and return as {@link LuaFunction}
|
||||||
* <p>
|
* <p>
|
||||||
@@ -853,7 +855,7 @@ public class LuaValue extends Varargs {
|
|||||||
* @see #optdouble(double)
|
* @see #optdouble(double)
|
||||||
* @see #TNUMBER
|
* @see #TNUMBER
|
||||||
*/
|
*/
|
||||||
public double checkdouble() { argerror("number"); return 0; }
|
public double checkdouble() { argerror("double"); return 0; }
|
||||||
|
|
||||||
/** Check that the value is a function , or throw {@link LuaError} if not
|
/** Check that the value is a function , or throw {@link LuaError} if not
|
||||||
* <p>
|
* <p>
|
||||||
@@ -2043,7 +2045,7 @@ public class LuaValue extends Varargs {
|
|||||||
* @see #eqmtcall(LuaValue, LuaValue, LuaValue, LuaValue)
|
* @see #eqmtcall(LuaValue, LuaValue, LuaValue, LuaValue)
|
||||||
* @see #EQ
|
* @see #EQ
|
||||||
*/
|
*/
|
||||||
public LuaValue eq( LuaValue val ) { return eq_b(val)? TRUE: FALSE; }
|
public LuaValue eq( LuaValue val ) { return this == val? TRUE: FALSE; }
|
||||||
|
|
||||||
/** Equals: Perform equality comparison with another value
|
/** Equals: Perform equality comparison with another value
|
||||||
* including metatag processing using {@link #EQ},
|
* including metatag processing using {@link #EQ},
|
||||||
@@ -3141,7 +3143,7 @@ public class LuaValue extends Varargs {
|
|||||||
* @return {@link LuaString} corresponding to the value if a string or number
|
* @return {@link LuaString} corresponding to the value if a string or number
|
||||||
* @throws LuaError if not a string or number
|
* @throws LuaError if not a string or number
|
||||||
*/
|
*/
|
||||||
public LuaString strvalue() { typerror("string or number"); return null; }
|
public LuaString strvalue() { typerror("strValue"); return null; }
|
||||||
|
|
||||||
/** Return this value as a strong reference, or null if it was weak and is no longer referenced.
|
/** Return this value as a strong reference, or null if it was weak and is no longer referenced.
|
||||||
* @return {@link LuaValue} referred to, or null if it was weak and is no longer referenced.
|
* @return {@link LuaValue} referred to, or null if it was weak and is no longer referenced.
|
||||||
@@ -3296,7 +3298,7 @@ public class LuaValue extends Varargs {
|
|||||||
if ((!res.isnil()) || (tm = t.metatag(INDEX)).isnil())
|
if ((!res.isnil()) || (tm = t.metatag(INDEX)).isnil())
|
||||||
return res;
|
return res;
|
||||||
} else if ((tm = t.metatag(INDEX)).isnil())
|
} else if ((tm = t.metatag(INDEX)).isnil())
|
||||||
t.indexerror(key.tojstring());
|
t.indexerror();
|
||||||
if (tm.isfunction())
|
if (tm.isfunction())
|
||||||
return tm.call(t, key);
|
return tm.call(t, key);
|
||||||
t = tm;
|
t = tm;
|
||||||
@@ -3324,7 +3326,7 @@ public class LuaValue extends Varargs {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if ((tm = t.metatag(NEWINDEX)).isnil())
|
} else if ((tm = t.metatag(NEWINDEX)).isnil())
|
||||||
throw new LuaError("table expected for set index ('" + key + "') value, got " + t.typename());
|
t.typerror("index");
|
||||||
if (tm.isfunction()) {
|
if (tm.isfunction()) {
|
||||||
tm.call(t, key, value);
|
tm.call(t, key, value);
|
||||||
return true;
|
return true;
|
||||||
@@ -3360,7 +3362,7 @@ public class LuaValue extends Varargs {
|
|||||||
protected LuaValue checkmetatag(LuaValue tag, String reason) {
|
protected LuaValue checkmetatag(LuaValue tag, String reason) {
|
||||||
LuaValue h = this.metatag(tag);
|
LuaValue h = this.metatag(tag);
|
||||||
if ( h.isnil() )
|
if ( h.isnil() )
|
||||||
throw new LuaError(reason + "a " + typename() + " value");
|
throw new LuaError(reason+typename());
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3387,8 +3389,8 @@ public class LuaValue extends Varargs {
|
|||||||
/** Throw {@link LuaError} indicating index was attempted on illegal type
|
/** Throw {@link LuaError} indicating index was attempted on illegal type
|
||||||
* @throws LuaError when called.
|
* @throws LuaError when called.
|
||||||
*/
|
*/
|
||||||
private void indexerror(String key) {
|
private void indexerror() {
|
||||||
error( "attempt to index ? (a "+typename()+" value) with key '" + key + "'" );
|
error( "attempt to index ? (a "+typename()+" value)" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Construct a {@link Varargs} around an array of {@link LuaValue}s.
|
/** Construct a {@link Varargs} around an array of {@link LuaValue}s.
|
||||||
|
|||||||
@@ -128,10 +128,6 @@ public class Print extends Lua {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void printValue( PrintStream ps, LuaValue v ) {
|
static void printValue( PrintStream ps, LuaValue v ) {
|
||||||
if (v == null) {
|
|
||||||
ps.print("null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch ( v.type() ) {
|
switch ( v.type() ) {
|
||||||
case LuaValue.TSTRING: printString( ps, (LuaString) v ); break;
|
case LuaValue.TSTRING: printString( ps, (LuaString) v ); break;
|
||||||
default: ps.print( v.tojstring() );
|
default: ps.print( v.tojstring() );
|
||||||
@@ -140,7 +136,7 @@ public class Print extends Lua {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void printConstant(PrintStream ps, Prototype f, int i) {
|
static void printConstant(PrintStream ps, Prototype f, int i) {
|
||||||
printValue( ps, i < f.k.length ? f.k[i] : LuaValue.valueOf("UNKNOWN_CONST_" + i) );
|
printValue( ps, f.k[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printUpvalue(PrintStream ps, Upvaldesc u) {
|
static void printUpvalue(PrintStream ps, Upvaldesc u) {
|
||||||
@@ -156,7 +152,7 @@ public class Print extends Lua {
|
|||||||
int[] code = f.code;
|
int[] code = f.code;
|
||||||
int pc, n = code.length;
|
int pc, n = code.length;
|
||||||
for (pc = 0; pc < n; pc++) {
|
for (pc = 0; pc < n; pc++) {
|
||||||
pc = printOpCode(f, pc);
|
printOpCode(f, pc);
|
||||||
ps.println();
|
ps.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,10 +161,9 @@ public class Print extends Lua {
|
|||||||
* Print an opcode in a prototype
|
* Print an opcode in a prototype
|
||||||
* @param f the {@link Prototype}
|
* @param f the {@link Prototype}
|
||||||
* @param pc the program counter to look up and print
|
* @param pc the program counter to look up and print
|
||||||
* @return pc same as above or changed
|
|
||||||
*/
|
*/
|
||||||
public static int printOpCode(Prototype f, int pc) {
|
public static void printOpCode(Prototype f, int pc) {
|
||||||
return printOpCode(ps,f,pc);
|
printOpCode(ps,f,pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -176,9 +171,8 @@ public class Print extends Lua {
|
|||||||
* @param ps the {@link PrintStream} to print to
|
* @param ps the {@link PrintStream} to print to
|
||||||
* @param f the {@link Prototype}
|
* @param f the {@link Prototype}
|
||||||
* @param pc the program counter to look up and print
|
* @param pc the program counter to look up and print
|
||||||
* @return pc same as above or changed
|
|
||||||
*/
|
*/
|
||||||
public static int printOpCode(PrintStream ps, Prototype f, int pc) {
|
public static void printOpCode(PrintStream ps, Prototype f, int pc) {
|
||||||
int[] code = f.code;
|
int[] code = f.code;
|
||||||
int i = code[pc];
|
int i = code[pc];
|
||||||
int o = GET_OPCODE(i);
|
int o = GET_OPCODE(i);
|
||||||
@@ -193,9 +187,6 @@ public class Print extends Lua {
|
|||||||
ps.print("[" + line + "] ");
|
ps.print("[" + line + "] ");
|
||||||
else
|
else
|
||||||
ps.print("[-] ");
|
ps.print("[-] ");
|
||||||
if (o >= OPNAMES.length - 1) {
|
|
||||||
ps.print("UNKNOWN_OP_" + o + " ");
|
|
||||||
} else {
|
|
||||||
ps.print(OPNAMES[o] + " ");
|
ps.print(OPNAMES[o] + " ");
|
||||||
switch (getOpMode(o)) {
|
switch (getOpMode(o)) {
|
||||||
case iABC:
|
case iABC:
|
||||||
@@ -227,19 +218,11 @@ public class Print extends Lua {
|
|||||||
case OP_GETUPVAL:
|
case OP_GETUPVAL:
|
||||||
case OP_SETUPVAL:
|
case OP_SETUPVAL:
|
||||||
ps.print(" ; ");
|
ps.print(" ; ");
|
||||||
if (b < f.upvalues.length) {
|
|
||||||
printUpvalue(ps, f.upvalues[b]);
|
printUpvalue(ps, f.upvalues[b]);
|
||||||
} else {
|
|
||||||
ps.print("UNKNOWN_UPVALUE_" + b);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case OP_GETTABUP:
|
case OP_GETTABUP:
|
||||||
ps.print(" ; ");
|
ps.print(" ; ");
|
||||||
if (b < f.upvalues.length) {
|
|
||||||
printUpvalue(ps, f.upvalues[b]);
|
printUpvalue(ps, f.upvalues[b]);
|
||||||
} else {
|
|
||||||
ps.print("UNKNOWN_UPVALUE_" + b);
|
|
||||||
}
|
|
||||||
ps.print(" ");
|
ps.print(" ");
|
||||||
if (ISK(c))
|
if (ISK(c))
|
||||||
printConstant(ps, f, INDEXK(c));
|
printConstant(ps, f, INDEXK(c));
|
||||||
@@ -248,11 +231,7 @@ public class Print extends Lua {
|
|||||||
break;
|
break;
|
||||||
case OP_SETTABUP:
|
case OP_SETTABUP:
|
||||||
ps.print(" ; ");
|
ps.print(" ; ");
|
||||||
if (a < f.upvalues.length) {
|
|
||||||
printUpvalue(ps, f.upvalues[a]);
|
printUpvalue(ps, f.upvalues[a]);
|
||||||
} else {
|
|
||||||
ps.print("UNKNOWN_UPVALUE_" + a);
|
|
||||||
}
|
|
||||||
ps.print(" ");
|
ps.print(" ");
|
||||||
if (ISK(b))
|
if (ISK(b))
|
||||||
printConstant(ps, f, INDEXK(b));
|
printConstant(ps, f, INDEXK(b));
|
||||||
@@ -299,15 +278,11 @@ public class Print extends Lua {
|
|||||||
ps.print(" ; to " + (sbx + pc + 2));
|
ps.print(" ; to " + (sbx + pc + 2));
|
||||||
break;
|
break;
|
||||||
case OP_CLOSURE:
|
case OP_CLOSURE:
|
||||||
if (bx < f.p.length) {
|
|
||||||
ps.print(" ; " + f.p[bx].getClass().getName());
|
ps.print(" ; " + f.p[bx].getClass().getName());
|
||||||
} else {
|
|
||||||
ps.print(" ; UNKNOWN_PROTYPE_" + bx);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case OP_SETLIST:
|
case OP_SETLIST:
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
ps.print(" ; " + ((int) code[++pc]) + " (stored in the next OP)");
|
ps.print(" ; " + ((int) code[++pc]));
|
||||||
else
|
else
|
||||||
ps.print(" ; " + ((int) c));
|
ps.print(" ; " + ((int) c));
|
||||||
break;
|
break;
|
||||||
@@ -318,8 +293,6 @@ public class Print extends Lua {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getline(Prototype f, int pc) {
|
private static int getline(Prototype f, int pc) {
|
||||||
return pc>0 && f.lineinfo!=null && pc<f.lineinfo.length? f.lineinfo[pc]: -1;
|
return pc>0 && f.lineinfo!=null && pc<f.lineinfo.length? f.lineinfo[pc]: -1;
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ public abstract class Varargs {
|
|||||||
* @return java double value if argument i is a number or string that converts to a number
|
* @return java double value if argument i is a number or string that converts to a number
|
||||||
* @exception LuaError if the argument is not a number
|
* @exception LuaError if the argument is not a number
|
||||||
* */
|
* */
|
||||||
public double checkdouble(int i) { return arg(i).checkdouble(); }
|
public double checkdouble(int i) { return arg(i).checknumber().todouble(); }
|
||||||
|
|
||||||
/** Return argument i as a function, or throw an error if an incompatible type.
|
/** Return argument i as a function, or throw an error if an incompatible type.
|
||||||
* @param i the index of the argument to test, 1 is the first argument
|
* @param i the index of the argument to test, 1 is the first argument
|
||||||
@@ -300,12 +300,12 @@ public abstract class Varargs {
|
|||||||
* */
|
* */
|
||||||
public LuaFunction checkfunction(int i) { return arg(i).checkfunction(); }
|
public LuaFunction checkfunction(int i) { return arg(i).checkfunction(); }
|
||||||
|
|
||||||
/** Return argument i as a java int value, or throw an error if it cannot be converted to one.
|
/** Return argument i as a java int value, discarding any fractional part, or throw an error if not a number.
|
||||||
* @param i the index of the argument to test, 1 is the first argument
|
* @param i the index of the argument to test, 1 is the first argument
|
||||||
* @return int value if argument i is a number or string that converts to a number
|
* @return int value with fraction discarded and truncated if necessary if argument i is number
|
||||||
* @exception LuaError if the argument cannot be represented by a java int value
|
* @exception LuaError if the argument is not a number
|
||||||
* */
|
* */
|
||||||
public int checkint(int i) { return arg(i).checkint(); }
|
public int checkint(int i) { return arg(i).checknumber().toint(); }
|
||||||
|
|
||||||
/** Return argument i as a java int value, or throw an error if not a number or is not representable by a java int.
|
/** Return argument i as a java int value, or throw an error if not a number or is not representable by a java int.
|
||||||
* @param i the index of the argument to test, 1 is the first argument
|
* @param i the index of the argument to test, 1 is the first argument
|
||||||
@@ -314,12 +314,12 @@ public abstract class Varargs {
|
|||||||
* */
|
* */
|
||||||
public LuaInteger checkinteger(int i) { return arg(i).checkinteger(); }
|
public LuaInteger checkinteger(int i) { return arg(i).checkinteger(); }
|
||||||
|
|
||||||
/** Return argument i as a java long value, or throw an error if it cannot be converted to one.
|
/** Return argument i as a java long value, discarding any fractional part, or throw an error if not a number.
|
||||||
* @param i the index of the argument to test, 1 is the first argument
|
* @param i the index of the argument to test, 1 is the first argument
|
||||||
* @return long value if argument i is a number or string that converts to a number
|
* @return long value with fraction discarded and truncated if necessary if argument i is number
|
||||||
* @exception LuaError if the argument cannot be represented by a java long value
|
* @exception LuaError if the argument is not a number
|
||||||
* */
|
* */
|
||||||
public long checklong(int i) { return arg(i).checklong(); }
|
public long checklong(int i) { return arg(i).checknumber().tolong(); }
|
||||||
|
|
||||||
/** Return argument i as a LuaNumber, or throw an error if not a number or string that can be converted to a number.
|
/** Return argument i as a LuaNumber, or throw an error if not a number or string that can be converted to a number.
|
||||||
* @param i the index of the argument to test, 1 is the first argument
|
* @param i the index of the argument to test, 1 is the first argument
|
||||||
@@ -707,10 +707,8 @@ public abstract class Varargs {
|
|||||||
/** Return Varargs that cannot be using a shared array for the storage, and is flattened.
|
/** Return Varargs that cannot be using a shared array for the storage, and is flattened.
|
||||||
* Internal utility method not intended to be called directly from user code.
|
* Internal utility method not intended to be called directly from user code.
|
||||||
* @return Varargs containing same values, but flattened and with a new array if needed.
|
* @return Varargs containing same values, but flattened and with a new array if needed.
|
||||||
* @exclude
|
|
||||||
* @hide
|
|
||||||
*/
|
*/
|
||||||
public Varargs dealias() {
|
Varargs dealias() {
|
||||||
int n = narg();
|
int n = narg();
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 0: return LuaValue.NONE;
|
case 0: return LuaValue.NONE;
|
||||||
|
|||||||
@@ -105,11 +105,6 @@ public class Constants extends Lua {
|
|||||||
((bc << POS_Bx) & MASK_Bx) ;
|
((bc << POS_Bx) & MASK_Bx) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CREATE_Ax(int o, int a) {
|
|
||||||
return ((o << POS_OP) & MASK_OP) |
|
|
||||||
((a << POS_Ax) & MASK_Ax) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// vector reallocation
|
// vector reallocation
|
||||||
|
|
||||||
static LuaValue[] realloc(LuaValue[] v, int n) {
|
static LuaValue[] realloc(LuaValue[] v, int n) {
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ import java.io.OutputStream;
|
|||||||
import org.luaj.vm2.Globals;
|
import org.luaj.vm2.Globals;
|
||||||
import org.luaj.vm2.LoadState;
|
import org.luaj.vm2.LoadState;
|
||||||
import org.luaj.vm2.LocVars;
|
import org.luaj.vm2.LocVars;
|
||||||
|
import org.luaj.vm2.Prototype;
|
||||||
import org.luaj.vm2.LuaString;
|
import org.luaj.vm2.LuaString;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
import org.luaj.vm2.Prototype;
|
|
||||||
|
|
||||||
|
|
||||||
/** Class to dump a {@link Prototype} into an output stream, as part of compiling.
|
/** Class to dump a {@link Prototype} into an output stream, as part of compiling.
|
||||||
@@ -85,7 +85,7 @@ public class DumpState {
|
|||||||
public static final int NUMBER_FORMAT_DEFAULT = NUMBER_FORMAT_FLOATS_OR_DOUBLES;
|
public static final int NUMBER_FORMAT_DEFAULT = NUMBER_FORMAT_FLOATS_OR_DOUBLES;
|
||||||
|
|
||||||
// header fields
|
// header fields
|
||||||
private boolean IS_LITTLE_ENDIAN = true;
|
private boolean IS_LITTLE_ENDIAN = false;
|
||||||
private int NUMBER_FORMAT = NUMBER_FORMAT_DEFAULT;
|
private int NUMBER_FORMAT = NUMBER_FORMAT_DEFAULT;
|
||||||
private int SIZEOF_LUA_NUMBER = 8;
|
private int SIZEOF_LUA_NUMBER = 8;
|
||||||
private static final int SIZEOF_INT = 4;
|
private static final int SIZEOF_INT = 4;
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public class FuncState extends Constants {
|
|||||||
Hashtable h; /* table to find (and reuse) elements in `k' */
|
Hashtable h; /* table to find (and reuse) elements in `k' */
|
||||||
FuncState prev; /* enclosing function */
|
FuncState prev; /* enclosing function */
|
||||||
LexState ls; /* lexical state */
|
LexState ls; /* lexical state */
|
||||||
|
LuaC.CompileState L; /* compiler being invoked */
|
||||||
BlockCnt bl; /* chain of current blocks */
|
BlockCnt bl; /* chain of current blocks */
|
||||||
int pc; /* next position to code (equivalent to `ncode') */
|
int pc; /* next position to code (equivalent to `ncode') */
|
||||||
int lasttarget; /* `pc' of last `jump target' */
|
int lasttarget; /* `pc' of last `jump target' */
|
||||||
@@ -112,8 +113,8 @@ public class FuncState extends Constants {
|
|||||||
void errorlimit (int limit, String what) {
|
void errorlimit (int limit, String what) {
|
||||||
// TODO: report message logic.
|
// TODO: report message logic.
|
||||||
String msg = (f.linedefined == 0) ?
|
String msg = (f.linedefined == 0) ?
|
||||||
ls.L.pushfstring("main function has more than "+limit+" "+what) :
|
L.pushfstring("main function has more than "+limit+" "+what) :
|
||||||
ls.L.pushfstring("function at line "+f.linedefined+" has more than "+limit+" "+what);
|
L.pushfstring("function at line "+f.linedefined+" has more than "+limit+" "+what);
|
||||||
ls.lexerror(msg, 0);
|
ls.lexerror(msg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,7 +480,7 @@ public class FuncState extends Constants {
|
|||||||
return ((Integer) h.get(v)).intValue();
|
return ((Integer) h.get(v)).intValue();
|
||||||
}
|
}
|
||||||
final int idx = this.nk;
|
final int idx = this.nk;
|
||||||
this.h.put(v, idx);
|
this.h.put(v, new Integer(idx));
|
||||||
final Prototype f = this.f;
|
final Prototype f = this.f;
|
||||||
if (f.k == null || nk + 1 >= f.k.length)
|
if (f.k == null || nk + 1 >= f.k.length)
|
||||||
f.k = realloc( f.k, nk*2 + 1 );
|
f.k = realloc( f.k, nk*2 + 1 );
|
||||||
@@ -580,11 +581,11 @@ public class FuncState extends Constants {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LexState.VK: {
|
case LexState.VK: {
|
||||||
this.codeK(reg, e.u.info);
|
this.codeABx(OP_LOADK, reg, e.u.info);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LexState.VKNUM: {
|
case LexState.VKNUM: {
|
||||||
this.codeK(reg, this.numberK(e.u.nval()));
|
this.codeABx(OP_LOADK, reg, this.numberK(e.u.nval()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LexState.VRELOCABLE: {
|
case LexState.VRELOCABLE: {
|
||||||
@@ -1116,20 +1117,6 @@ public class FuncState extends Constants {
|
|||||||
return this.code(CREATE_ABx(o, a, bc), this.ls.lastline);
|
return this.code(CREATE_ABx(o, a, bc), this.ls.lastline);
|
||||||
}
|
}
|
||||||
|
|
||||||
int codeextraarg(int a) {
|
|
||||||
_assert(a <= MAXARG_Ax);
|
|
||||||
return this.code(CREATE_Ax(OP_EXTRAARG, a), this.ls.lastline);
|
|
||||||
}
|
|
||||||
|
|
||||||
int codeK(int reg, int k) {
|
|
||||||
if (k <= MAXARG_Bx)
|
|
||||||
return codeABx(OP_LOADK, reg, k);
|
|
||||||
else {
|
|
||||||
int p = codeABx(OP_LOADKX, reg, 0);
|
|
||||||
codeextraarg(k);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setlist(int base, int nelems, int tostore) {
|
void setlist(int base, int nelems, int tostore) {
|
||||||
int c = (nelems - 1) / LFIELDS_PER_FLUSH + 1;
|
int c = (nelems - 1) / LFIELDS_PER_FLUSH + 1;
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public class LexState extends Constants {
|
|||||||
static {
|
static {
|
||||||
for ( int i=0; i<NUM_RESERVED; i++ ) {
|
for ( int i=0; i<NUM_RESERVED; i++ ) {
|
||||||
LuaString ts = (LuaString) LuaValue.valueOf( luaX_tokens[i] );
|
LuaString ts = (LuaString) LuaValue.valueOf( luaX_tokens[i] );
|
||||||
RESERVED.put(ts, FIRST_RESERVED+i);
|
RESERVED.put(ts, new Integer(FIRST_RESERVED+i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ public class LexState extends Constants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isspace(int c) {
|
private boolean isspace(int c) {
|
||||||
return (c >= 0 && c <= ' ');
|
return (c <= ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -388,13 +388,8 @@ public class LexState extends Constants {
|
|||||||
seminfo.r = LuaValue.ZERO;
|
seminfo.r = LuaValue.ZERO;
|
||||||
else if (str.indexOf('x')>=0 || str.indexOf('X')>=0)
|
else if (str.indexOf('x')>=0 || str.indexOf('X')>=0)
|
||||||
seminfo.r = strx2number(str, seminfo);
|
seminfo.r = strx2number(str, seminfo);
|
||||||
else {
|
else
|
||||||
try {
|
|
||||||
seminfo.r = LuaValue.valueOf(Double.parseDouble(str.trim()));
|
seminfo.r = LuaValue.valueOf(Double.parseDouble(str.trim()));
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
lexerror("malformed number (" + e.getMessage() + ")", TK_NUMBER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,6 +408,7 @@ public class LexState extends Constants {
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
save('\0');
|
||||||
String str = new String(buff, 0, nbuff);
|
String str = new String(buff, 0, nbuff);
|
||||||
str2d(str, seminfo);
|
str2d(str, seminfo);
|
||||||
}
|
}
|
||||||
@@ -589,13 +585,6 @@ public class LexState extends Constants {
|
|||||||
inclinenumber();
|
inclinenumber();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case ' ':
|
|
||||||
case '\f':
|
|
||||||
case '\t':
|
|
||||||
case 0x0B: /* \v */ {
|
|
||||||
nextChar();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
case '-': {
|
case '-': {
|
||||||
nextChar();
|
nextChar();
|
||||||
if (current != '-')
|
if (current != '-')
|
||||||
@@ -699,12 +688,19 @@ public class LexState extends Constants {
|
|||||||
return TK_EOS;
|
return TK_EOS;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
if (isalpha(current) || current == '_') {
|
if (isspace(current)) {
|
||||||
|
_assert (!currIsNewline());
|
||||||
|
nextChar();
|
||||||
|
continue;
|
||||||
|
} else if (isdigit(current)) {
|
||||||
|
read_numeral(seminfo);
|
||||||
|
return TK_NUMBER;
|
||||||
|
} else if (isalpha(current) || current == '_') {
|
||||||
/* identifier or reserved word */
|
/* identifier or reserved word */
|
||||||
LuaString ts;
|
LuaString ts;
|
||||||
do {
|
do {
|
||||||
save_and_next();
|
save_and_next();
|
||||||
} while (isalnum(current));
|
} while (isalnum(current) || current == '_');
|
||||||
ts = newstring(buff, 0, nbuff);
|
ts = newstring(buff, 0, nbuff);
|
||||||
if ( RESERVED.containsKey(ts) )
|
if ( RESERVED.containsKey(ts) )
|
||||||
return ((Integer)RESERVED.get(ts)).intValue();
|
return ((Integer)RESERVED.get(ts)).intValue();
|
||||||
@@ -1748,7 +1744,7 @@ public class LexState extends Constants {
|
|||||||
fs.checkrepeated(dyd.label, dyd.n_label, label); /* check for repeated labels */
|
fs.checkrepeated(dyd.label, dyd.n_label, label); /* check for repeated labels */
|
||||||
checknext(TK_DBCOLON); /* skip double colon */
|
checknext(TK_DBCOLON); /* skip double colon */
|
||||||
/* create new entry for this label */
|
/* create new entry for this label */
|
||||||
l = newlabelentry(dyd.label=grow(dyd.label, dyd.n_label+1), dyd.n_label++, label, line, fs.getlabel());
|
l = newlabelentry(dyd.label=grow(dyd.label, dyd.n_label+1), dyd.n_label++, label, line, fs.pc);
|
||||||
skipnoopstat(); /* skip other no-op statements */
|
skipnoopstat(); /* skip other no-op statements */
|
||||||
if (block_follow(false)) { /* label is last no-op statement in the block? */
|
if (block_follow(false)) { /* label is last no-op statement in the block? */
|
||||||
/* assume that locals are already out of scope */
|
/* assume that locals are already out of scope */
|
||||||
@@ -1849,7 +1845,7 @@ public class LexState extends Constants {
|
|||||||
if (this.testnext(','))
|
if (this.testnext(','))
|
||||||
this.exp1(); /* optional step */
|
this.exp1(); /* optional step */
|
||||||
else { /* default step = 1 */
|
else { /* default step = 1 */
|
||||||
fs.codeK(fs.freereg, fs.numberK(LuaInteger.valueOf(1)));
|
fs.codeABx(Lua.OP_LOADK, fs.freereg, fs.numberK(LuaInteger.valueOf(1)));
|
||||||
fs.reserveregs(1);
|
fs.reserveregs(1);
|
||||||
}
|
}
|
||||||
this.forbody(base, line, 1, true);
|
this.forbody(base, line, 1, true);
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ public class LuaC extends Constants implements Globals.Compiler, Globals.Loader
|
|||||||
protected CompileState() {}
|
protected CompileState() {}
|
||||||
|
|
||||||
/** Parse the input */
|
/** Parse the input */
|
||||||
Prototype luaY_parser(InputStream z, String name) throws IOException{
|
private Prototype luaY_parser(InputStream z, String name) throws IOException{
|
||||||
LexState lexstate = new LexState(this, z);
|
LexState lexstate = new LexState(this, z);
|
||||||
FuncState funcstate = new FuncState();
|
FuncState funcstate = new FuncState();
|
||||||
// lexstate.buff = buff;
|
// lexstate.buff = buff;
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
System.gc();
|
System.gc();
|
||||||
return LuaValue.TRUE;
|
return LuaValue.TRUE;
|
||||||
} else {
|
} else {
|
||||||
argerror(1, "invalid option '" + s + "'");
|
this.argerror("gc op");
|
||||||
}
|
}
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
@@ -173,16 +173,16 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
// "error", // ( message [,level] ) -> ERR
|
// "error", // ( message [,level] ) -> ERR
|
||||||
static final class error extends TwoArgFunction {
|
static final class error extends TwoArgFunction {
|
||||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||||
if (arg1.isnil()) throw new LuaError(NIL);
|
throw arg1.isnil()? new LuaError(null, arg2.optint(1)):
|
||||||
if (!arg1.isstring() || arg2.optint(1) == 0) throw new LuaError(arg1);
|
arg1.isstring()? new LuaError(arg1.tojstring(), arg2.optint(1)):
|
||||||
throw new LuaError(arg1.tojstring(), arg2.optint(1));
|
new LuaError(arg1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// "getmetatable", // ( object ) -> table
|
// "getmetatable", // ( object ) -> table
|
||||||
static final class getmetatable extends LibFunction {
|
static final class getmetatable extends LibFunction {
|
||||||
public LuaValue call() {
|
public LuaValue call() {
|
||||||
return argerror(1, "value expected");
|
return argerror(1, "value");
|
||||||
}
|
}
|
||||||
public LuaValue call(LuaValue arg) {
|
public LuaValue call(LuaValue arg) {
|
||||||
LuaValue mt = arg.getmetatable();
|
LuaValue mt = arg.getmetatable();
|
||||||
@@ -193,9 +193,7 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
final class load extends VarArgFunction {
|
final class load extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaValue ld = args.arg1();
|
LuaValue ld = args.arg1();
|
||||||
if (!ld.isstring() && !ld.isfunction()) {
|
args.argcheck(ld.isstring() || ld.isfunction(), 1, "ld must be string or function");
|
||||||
throw new LuaError("bad argument #1 to 'load' (string or function expected, got " + ld.typename() + ")");
|
|
||||||
}
|
|
||||||
String source = args.optjstring(2, ld.isstring()? ld.tojstring(): "=(load)");
|
String source = args.optjstring(2, ld.isstring()? ld.tojstring(): "=(load)");
|
||||||
String mode = args.optjstring(3, "bt");
|
String mode = args.optjstring(3, "bt");
|
||||||
LuaValue env = args.optvalue(4, globals);
|
LuaValue env = args.optvalue(4, globals);
|
||||||
@@ -251,7 +249,7 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
LuaString s = tostring.call( args.arg(i) ).strvalue();
|
LuaString s = tostring.call( args.arg(i) ).strvalue();
|
||||||
globals.STDOUT.print(s.tojstring());
|
globals.STDOUT.print(s.tojstring());
|
||||||
}
|
}
|
||||||
globals.STDOUT.print('\n');
|
globals.STDOUT.println();
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -260,10 +258,10 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
// "rawequal", // (v1, v2) -> boolean
|
// "rawequal", // (v1, v2) -> boolean
|
||||||
static final class rawequal extends LibFunction {
|
static final class rawequal extends LibFunction {
|
||||||
public LuaValue call() {
|
public LuaValue call() {
|
||||||
return argerror(1, "value expected");
|
return argerror(1, "value");
|
||||||
}
|
}
|
||||||
public LuaValue call(LuaValue arg) {
|
public LuaValue call(LuaValue arg) {
|
||||||
return argerror(2, "value expected");
|
return argerror(2, "value");
|
||||||
}
|
}
|
||||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||||
return valueOf(arg1.raweq(arg2));
|
return valueOf(arg1.raweq(arg2));
|
||||||
@@ -271,9 +269,12 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// "rawget", // (table, index) -> value
|
// "rawget", // (table, index) -> value
|
||||||
static final class rawget extends TableLibFunction {
|
static final class rawget extends LibFunction {
|
||||||
|
public LuaValue call() {
|
||||||
|
return argerror(1, "value");
|
||||||
|
}
|
||||||
public LuaValue call(LuaValue arg) {
|
public LuaValue call(LuaValue arg) {
|
||||||
return argerror(2, "value expected");
|
return argerror(2, "value");
|
||||||
}
|
}
|
||||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||||
return arg1.checktable().rawget(arg2);
|
return arg1.checktable().rawget(arg2);
|
||||||
@@ -289,17 +290,16 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// "rawset", // (table, index, value) -> table
|
// "rawset", // (table, index, value) -> table
|
||||||
static final class rawset extends TableLibFunction {
|
static final class rawset extends LibFunction {
|
||||||
public LuaValue call(LuaValue table) {
|
public LuaValue call(LuaValue table) {
|
||||||
return argerror(2,"value expected");
|
return argerror(2,"value");
|
||||||
}
|
}
|
||||||
public LuaValue call(LuaValue table, LuaValue index) {
|
public LuaValue call(LuaValue table, LuaValue index) {
|
||||||
return argerror(3,"value expected");
|
return argerror(3,"value");
|
||||||
}
|
}
|
||||||
public LuaValue call(LuaValue table, LuaValue index, LuaValue value) {
|
public LuaValue call(LuaValue table, LuaValue index, LuaValue value) {
|
||||||
LuaTable t = table.checktable();
|
LuaTable t = table.checktable();
|
||||||
if (!index.isvalidkey()) argerror(2, "table index is nil");
|
t.rawset(index.checknotnil(), value);
|
||||||
t.rawset(index, value);
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,9 +318,9 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// "setmetatable", // (table, metatable) -> table
|
// "setmetatable", // (table, metatable) -> table
|
||||||
static final class setmetatable extends TableLibFunction {
|
static final class setmetatable extends LibFunction {
|
||||||
public LuaValue call(LuaValue table) {
|
public LuaValue call(LuaValue table) {
|
||||||
return argerror(2,"nil or table expected");
|
return argerror(2,"value");
|
||||||
}
|
}
|
||||||
public LuaValue call(LuaValue table, LuaValue metatable) {
|
public LuaValue call(LuaValue table, LuaValue metatable) {
|
||||||
final LuaValue mt0 = table.checktable().getmetatable();
|
final LuaValue mt0 = table.checktable().getmetatable();
|
||||||
@@ -465,12 +465,10 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
this.func = func;
|
this.func = func;
|
||||||
}
|
}
|
||||||
public int read() throws IOException {
|
public int read() throws IOException {
|
||||||
if ( remaining < 0 )
|
if ( remaining <= 0 ) {
|
||||||
return -1;
|
|
||||||
if ( remaining == 0 ) {
|
|
||||||
LuaValue s = func.call();
|
LuaValue s = func.call();
|
||||||
if ( s.isnil() )
|
if ( s.isnil() )
|
||||||
return remaining = -1;
|
return -1;
|
||||||
LuaString ls = s.strvalue();
|
LuaString ls = s.strvalue();
|
||||||
bytes = ls.m_bytes;
|
bytes = ls.m_bytes;
|
||||||
offset = ls.m_offset;
|
offset = ls.m_offset;
|
||||||
@@ -479,7 +477,7 @@ public class BaseLib extends TwoArgFunction implements ResourceFinder {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
--remaining;
|
--remaining;
|
||||||
return 0xFF&bytes[offset++];
|
return bytes[offset++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public class Bit32Lib extends TwoArgFunction {
|
|||||||
"arshift", "lrotate", "lshift", "rrotate", "rshift"
|
"arshift", "lrotate", "lshift", "rrotate", "rshift"
|
||||||
});
|
});
|
||||||
env.set("bit32", t);
|
env.set("bit32", t);
|
||||||
if (!env.get("package").isnil()) env.get("package").get("loaded").set("bit32", t);
|
env.get("package").get("loaded").set("bit32", t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,10 +79,10 @@ public class CoroutineLib extends TwoArgFunction {
|
|||||||
coroutine.set("resume", new resume());
|
coroutine.set("resume", new resume());
|
||||||
coroutine.set("running", new running());
|
coroutine.set("running", new running());
|
||||||
coroutine.set("status", new status());
|
coroutine.set("status", new status());
|
||||||
coroutine.set("yield", new Yield());
|
coroutine.set("yield", new yield());
|
||||||
coroutine.set("wrap", new wrap());
|
coroutine.set("wrap", new wrap());
|
||||||
env.set("coroutine", coroutine);
|
env.set("coroutine", coroutine);
|
||||||
if (!env.get("package").isnil()) env.get("package").get("loaded").set("coroutine", coroutine);
|
env.get("package").get("loaded").set("coroutine", coroutine);
|
||||||
return coroutine;
|
return coroutine;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ public class CoroutineLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class resume extends VarArgFunction {
|
final class resume extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
final LuaThread t = args.checkthread(1);
|
final LuaThread t = args.checkthread(1);
|
||||||
return t.resume( args.subargs(2) );
|
return t.resume( args.subargs(2) );
|
||||||
@@ -113,7 +113,7 @@ public class CoroutineLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class Yield extends VarArgFunction {
|
final class yield extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
return globals.yield( args );
|
return globals.yield( args );
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ public class CoroutineLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class wrapper extends VarArgFunction {
|
final class wrapper extends VarArgFunction {
|
||||||
final LuaThread luathread;
|
final LuaThread luathread;
|
||||||
wrapper(LuaThread luathread) {
|
wrapper(LuaThread luathread) {
|
||||||
this.luathread = luathread;
|
this.luathread = luathread;
|
||||||
|
|||||||
@@ -21,9 +21,6 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.vm2.lib;
|
package org.luaj.vm2.lib;
|
||||||
|
|
||||||
import java.util.concurrent.locks.Lock;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
|
|
||||||
import org.luaj.vm2.Globals;
|
import org.luaj.vm2.Globals;
|
||||||
import org.luaj.vm2.Lua;
|
import org.luaj.vm2.Lua;
|
||||||
import org.luaj.vm2.LuaBoolean;
|
import org.luaj.vm2.LuaBoolean;
|
||||||
@@ -87,27 +84,27 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
try { TRACE = (null != System.getProperty("TRACE")); } catch (Exception e) {}
|
try { TRACE = (null != System.getProperty("TRACE")); } catch (Exception e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final LuaString LUA = valueOf("Lua");
|
private static final LuaString LUA = valueOf("Lua");
|
||||||
private static final LuaString QMARK = valueOf("?");
|
private static final LuaString QMARK = valueOf("?");
|
||||||
private static final LuaString CALL = valueOf("call");
|
private static final LuaString CALL = valueOf("call");
|
||||||
private static final LuaString LINE = valueOf("line");
|
private static final LuaString LINE = valueOf("line");
|
||||||
private static final LuaString COUNT = valueOf("count");
|
private static final LuaString COUNT = valueOf("count");
|
||||||
private static final LuaString RETURN = valueOf("return");
|
private static final LuaString RETURN = valueOf("return");
|
||||||
|
|
||||||
static final LuaString FUNC = valueOf("func");
|
private static final LuaString FUNC = valueOf("func");
|
||||||
static final LuaString ISTAILCALL = valueOf("istailcall");
|
private static final LuaString ISTAILCALL = valueOf("istailcall");
|
||||||
static final LuaString ISVARARG = valueOf("isvararg");
|
private static final LuaString ISVARARG = valueOf("isvararg");
|
||||||
static final LuaString NUPS = valueOf("nups");
|
private static final LuaString NUPS = valueOf("nups");
|
||||||
static final LuaString NPARAMS = valueOf("nparams");
|
private static final LuaString NPARAMS = valueOf("nparams");
|
||||||
static final LuaString NAME = valueOf("name");
|
private static final LuaString NAME = valueOf("name");
|
||||||
static final LuaString NAMEWHAT = valueOf("namewhat");
|
private static final LuaString NAMEWHAT = valueOf("namewhat");
|
||||||
static final LuaString WHAT = valueOf("what");
|
private static final LuaString WHAT = valueOf("what");
|
||||||
static final LuaString SOURCE = valueOf("source");
|
private static final LuaString SOURCE = valueOf("source");
|
||||||
static final LuaString SHORT_SRC = valueOf("short_src");
|
private static final LuaString SHORT_SRC = valueOf("short_src");
|
||||||
static final LuaString LINEDEFINED = valueOf("linedefined");
|
private static final LuaString LINEDEFINED = valueOf("linedefined");
|
||||||
static final LuaString LASTLINEDEFINED = valueOf("lastlinedefined");
|
private static final LuaString LASTLINEDEFINED = valueOf("lastlinedefined");
|
||||||
static final LuaString CURRENTLINE = valueOf("currentline");
|
private static final LuaString CURRENTLINE = valueOf("currentline");
|
||||||
static final LuaString ACTIVELINES = valueOf("activelines");
|
private static final LuaString ACTIVELINES = valueOf("activelines");
|
||||||
|
|
||||||
Globals globals;
|
Globals globals;
|
||||||
|
|
||||||
@@ -138,7 +135,7 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
debug.set("upvalueid", new upvalueid());
|
debug.set("upvalueid", new upvalueid());
|
||||||
debug.set("upvaluejoin", new upvaluejoin());
|
debug.set("upvaluejoin", new upvaluejoin());
|
||||||
env.set("debug", debug);
|
env.set("debug", debug);
|
||||||
if (!env.get("package").isnil()) env.get("package").get("loaded").set("debug", debug);
|
env.get("package").get("loaded").set("debug", debug);
|
||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,7 +234,7 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// debug.getmetatable (value)
|
// debug.getmetatable (value)
|
||||||
static final class getmetatable extends LibFunction {
|
final class getmetatable extends LibFunction {
|
||||||
public LuaValue call(LuaValue v) {
|
public LuaValue call(LuaValue v) {
|
||||||
LuaValue mt = v.getmetatable();
|
LuaValue mt = v.getmetatable();
|
||||||
return mt != null? mt: NIL;
|
return mt != null? mt: NIL;
|
||||||
@@ -314,7 +311,7 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// debug.setmetatable (value, table)
|
// debug.setmetatable (value, table)
|
||||||
static final class setmetatable extends TwoArgFunction {
|
final class setmetatable extends TwoArgFunction {
|
||||||
public LuaValue call(LuaValue value, LuaValue table) {
|
public LuaValue call(LuaValue value, LuaValue table) {
|
||||||
LuaValue mt = table.opttable(null);
|
LuaValue mt = table.opttable(null);
|
||||||
switch ( value.type() ) {
|
switch ( value.type() ) {
|
||||||
@@ -331,7 +328,7 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// debug.setupvalue (f, up, value)
|
// debug.setupvalue (f, up, value)
|
||||||
static final class setupvalue extends VarArgFunction {
|
final class setupvalue extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaValue func = args.checkfunction(1);
|
LuaValue func = args.checkfunction(1);
|
||||||
int up = args.checkint(2);
|
int up = args.checkint(2);
|
||||||
@@ -349,7 +346,7 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// debug.setuservalue (udata, value)
|
// debug.setuservalue (udata, value)
|
||||||
static final class setuservalue extends VarArgFunction {
|
final class setuservalue extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
Object o = args.checkuserdata(1);
|
Object o = args.checkuserdata(1);
|
||||||
LuaValue v = args.checkvalue(2);
|
LuaValue v = args.checkvalue(2);
|
||||||
@@ -373,7 +370,7 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// debug.upvalueid (f, n)
|
// debug.upvalueid (f, n)
|
||||||
static final class upvalueid extends VarArgFunction {
|
final class upvalueid extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaValue func = args.checkfunction(1);
|
LuaValue func = args.checkfunction(1);
|
||||||
int up = args.checkint(2);
|
int up = args.checkint(2);
|
||||||
@@ -388,7 +385,7 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// debug.upvaluejoin (f1, n1, f2, n2)
|
// debug.upvaluejoin (f1, n1, f2, n2)
|
||||||
static final class upvaluejoin extends VarArgFunction {
|
final class upvaluejoin extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaClosure f1 = args.checkclosure(1);
|
LuaClosure f1 = args.checkclosure(1);
|
||||||
int n1 = args.checkint(2);
|
int n1 = args.checkint(2);
|
||||||
@@ -445,10 +442,6 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
return callstack().traceback(level);
|
return callstack().traceback(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CallFrame getCallFrame(int level) {
|
|
||||||
return callstack().getCallFrame(level);
|
|
||||||
}
|
|
||||||
|
|
||||||
void callHook(LuaThread.State s, LuaValue type, LuaValue arg) {
|
void callHook(LuaThread.State s, LuaValue type, LuaValue arg) {
|
||||||
if (s.inhook || s.hookfunc == null) return;
|
if (s.inhook || s.hookfunc == null) return;
|
||||||
s.inhook = true;
|
s.inhook = true;
|
||||||
@@ -510,22 +503,14 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
final static CallFrame[] EMPTY = {};
|
final static CallFrame[] EMPTY = {};
|
||||||
CallFrame[] frame = EMPTY;
|
CallFrame[] frame = EMPTY;
|
||||||
int calls = 0;
|
int calls = 0;
|
||||||
Lock lock = new ReentrantLock();
|
|
||||||
|
|
||||||
CallStack() {}
|
CallStack() {}
|
||||||
|
|
||||||
int currentline() {
|
synchronized int currentline() {
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
return calls > 0? frame[calls-1].currentline(): -1;
|
return calls > 0? frame[calls-1].currentline(): -1;
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private CallFrame pushcall() {
|
private synchronized CallFrame pushcall() {
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
if (calls >= frame.length) {
|
if (calls >= frame.length) {
|
||||||
int n = Math.max(4, frame.length * 3 / 2);
|
int n = Math.max(4, frame.length * 3 / 2);
|
||||||
CallFrame[] f = new CallFrame[n];
|
CallFrame[] f = new CallFrame[n];
|
||||||
@@ -537,48 +522,24 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
f[i].previous = f[i-1];
|
f[i].previous = f[i-1];
|
||||||
}
|
}
|
||||||
return frame[calls++];
|
return frame[calls++];
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final void onCall(LuaFunction function) {
|
final synchronized void onCall(LuaFunction function) {
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
pushcall().set(function);
|
pushcall().set(function);
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final void onCall(LuaClosure function, Varargs varargs, LuaValue[] stack) {
|
final synchronized void onCall(LuaClosure function, Varargs varargs, LuaValue[] stack) {
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
pushcall().set(function, varargs, stack);
|
pushcall().set(function, varargs, stack);
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
final synchronized void onReturn() {
|
||||||
|
|
||||||
final void onReturn() {
|
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
if (calls > 0)
|
if (calls > 0)
|
||||||
frame[--calls].reset();
|
frame[--calls].reset();
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final void onInstruction(int pc, Varargs v, int top) {
|
final synchronized void onInstruction(int pc, Varargs v, int top) {
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
if (calls > 0)
|
if (calls > 0)
|
||||||
frame[calls-1].instr(pc, v, top);
|
frame[calls-1].instr(pc, v, top);
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -586,9 +547,7 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
* @param level
|
* @param level
|
||||||
* @return String containing the traceback.
|
* @return String containing the traceback.
|
||||||
*/
|
*/
|
||||||
String traceback(int level) {
|
synchronized String traceback(int level) {
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append( "stack traceback:" );
|
sb.append( "stack traceback:" );
|
||||||
for (DebugLib.CallFrame c; (c = getCallFrame(level++)) != null; ) {
|
for (DebugLib.CallFrame c; (c = getCallFrame(level++)) != null; ) {
|
||||||
@@ -606,48 +565,28 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
sb.append( ar.name );
|
sb.append( ar.name );
|
||||||
sb.append( '\'' );
|
sb.append( '\'' );
|
||||||
} else {
|
} else {
|
||||||
sb.append( "function <" );
|
sb.append( "function <"+c.shortsource()+":"+c.linedefined()+">" );
|
||||||
sb.append( c.shortsource() );
|
|
||||||
sb.append( ':' );
|
|
||||||
sb.append( c.linedefined() );
|
|
||||||
sb.append( '>' );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb.append("\n\t[Java]: in ?");
|
sb.append("\n\t[Java]: in ?");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
synchronized DebugLib.CallFrame getCallFrame(int level) {
|
||||||
|
|
||||||
DebugLib.CallFrame getCallFrame(int level) {
|
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
if (level < 1 || level > calls)
|
if (level < 1 || level > calls)
|
||||||
return null;
|
return null;
|
||||||
return frame[calls-level];
|
return frame[calls-level];
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugLib.CallFrame findCallFrame(LuaValue func) {
|
synchronized DebugLib.CallFrame findCallFrame(LuaValue func) {
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
for (int i = 1; i <= calls; ++i)
|
for (int i = 1; i <= calls; ++i)
|
||||||
if (frame[calls-i].f == func)
|
if (frame[calls-i].f == func)
|
||||||
return frame[i];
|
return frame[i];
|
||||||
return null;
|
return null;
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DebugInfo auxgetinfo(String what, LuaFunction f, CallFrame ci) {
|
synchronized DebugInfo auxgetinfo(String what, LuaFunction f, CallFrame ci) {
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
DebugInfo ar = new DebugInfo();
|
DebugInfo ar = new DebugInfo();
|
||||||
for (int i = 0, n = what.length(); i < n; ++i) {
|
for (int i = 0, n = what.length(); i < n; ++i) {
|
||||||
switch (what.charAt(i)) {
|
switch (what.charAt(i)) {
|
||||||
@@ -698,13 +637,11 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ar;
|
return ar;
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CallFrame {
|
}
|
||||||
|
|
||||||
|
static class CallFrame {
|
||||||
LuaFunction f;
|
LuaFunction f;
|
||||||
int pc;
|
int pc;
|
||||||
int top;
|
int top;
|
||||||
@@ -736,21 +673,21 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
Varargs getLocal(int i) {
|
Varargs getLocal(int i) {
|
||||||
LuaString name = getlocalname(i);
|
LuaString name = getlocalname(i);
|
||||||
if ( i >= 1 && i <= stack.length && stack[i-1] != null )
|
if ( name != null )
|
||||||
return varargsOf( name == null ? NIL : name, stack[i-1] );
|
return varargsOf( name, stack[i-1] );
|
||||||
else
|
else
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
Varargs setLocal(int i, LuaValue value) {
|
Varargs setLocal(int i, LuaValue value) {
|
||||||
LuaString name = getlocalname(i);
|
LuaString name = getlocalname(i);
|
||||||
if ( i >= 1 && i <= stack.length && stack[i-1] != null ) {
|
if ( name != null ) {
|
||||||
stack[i-1] = value;
|
stack[i-1] = value;
|
||||||
return name == null ? NIL : name;
|
return name;
|
||||||
} else {
|
} else {
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public int currentline() {
|
int currentline() {
|
||||||
if ( !f.isclosure() ) return -1;
|
if ( !f.isclosure() ) return -1;
|
||||||
int[] li = f.checkclosure().p.lineinfo;
|
int[] li = f.checkclosure().p.lineinfo;
|
||||||
return li==null || pc<0 || pc>=li.length? -1: li[pc];
|
return li==null || pc<0 || pc>=li.length? -1: li[pc];
|
||||||
@@ -759,7 +696,7 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
if ( !f.isclosure() ) return f.tojstring();
|
if ( !f.isclosure() ) return f.tojstring();
|
||||||
return f.checkclosure().p.shortsource() + ":" + currentline();
|
return f.checkclosure().p.shortsource() + ":" + currentline();
|
||||||
}
|
}
|
||||||
int linedefined() {
|
private int linedefined() {
|
||||||
return f.isclosure()? f.checkclosure().p.linedefined: -1;
|
return f.isclosure()? f.checkclosure().p.linedefined: -1;
|
||||||
}
|
}
|
||||||
LuaString getlocalname(int index) {
|
LuaString getlocalname(int index) {
|
||||||
@@ -855,13 +792,13 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
LuaString vn = (Lua.GET_OPCODE(i) == Lua.OP_GETTABLE) /* name of indexed variable */
|
LuaString vn = (Lua.GET_OPCODE(i) == Lua.OP_GETTABLE) /* name of indexed variable */
|
||||||
? p.getlocalname(t + 1, pc)
|
? p.getlocalname(t + 1, pc)
|
||||||
: (t < p.upvalues.length ? p.upvalues[t].name : QMARK);
|
: (t < p.upvalues.length ? p.upvalues[t].name : QMARK);
|
||||||
String jname = kname(p, pc, k);
|
name = kname(p, k);
|
||||||
return new NameWhat( jname, vn != null && vn.eq_b(ENV)? "global": "field" );
|
return new NameWhat( name.tojstring(), vn != null && vn.eq_b(ENV)? "global": "field" );
|
||||||
}
|
}
|
||||||
case Lua.OP_GETUPVAL: {
|
case Lua.OP_GETUPVAL: {
|
||||||
int u = Lua.GETARG_B(i); /* upvalue index */
|
int u = Lua.GETARG_B(i); /* upvalue index */
|
||||||
name = u < p.upvalues.length ? p.upvalues[u].name : QMARK;
|
name = u < p.upvalues.length ? p.upvalues[u].name : QMARK;
|
||||||
return name == null ? null : new NameWhat( name.tojstring(), "upvalue" );
|
return new NameWhat( name.tojstring(), "upvalue" );
|
||||||
}
|
}
|
||||||
case Lua.OP_LOADK:
|
case Lua.OP_LOADK:
|
||||||
case Lua.OP_LOADKX: {
|
case Lua.OP_LOADKX: {
|
||||||
@@ -875,8 +812,8 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
case Lua.OP_SELF: {
|
case Lua.OP_SELF: {
|
||||||
int k = Lua.GETARG_C(i); /* key index */
|
int k = Lua.GETARG_C(i); /* key index */
|
||||||
String jname = kname(p, pc, k);
|
name = kname(p, k);
|
||||||
return new NameWhat( jname, "method" );
|
return new NameWhat( name.tojstring(), "method" );
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -885,20 +822,11 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
return null; /* no useful name found */
|
return null; /* no useful name found */
|
||||||
}
|
}
|
||||||
|
|
||||||
static String kname(Prototype p, int pc, int c) {
|
static LuaString kname(Prototype p, int c) {
|
||||||
if (Lua.ISK(c)) { /* is 'c' a constant? */
|
if (Lua.ISK(c) && p.k[Lua.INDEXK(c)].isstring())
|
||||||
LuaValue k = p.k[Lua.INDEXK(c)];
|
return p.k[Lua.INDEXK(c)].strvalue();
|
||||||
if (k.isstring()) { /* literal constant? */
|
else
|
||||||
return k.tojstring(); /* it is its own name */
|
return QMARK;
|
||||||
} /* else no reasonable name found */
|
|
||||||
} else { /* 'c' is a register */
|
|
||||||
NameWhat what = getobjname(p, pc, c); /* search for 'c' */
|
|
||||||
if (what != null && "constant".equals(what.namewhat)) { /* found a constant name? */
|
|
||||||
return what.name; /* 'name' already filled */
|
|
||||||
}
|
|
||||||
/* else no reasonable name found */
|
|
||||||
}
|
|
||||||
return "?"; /* no reasonable name found */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -939,10 +867,6 @@ public class DebugLib extends TwoArgFunction {
|
|||||||
if (reg == a) setreg = pc; /* jumped code can change 'a' */
|
if (reg == a) setreg = pc; /* jumped code can change 'a' */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Lua.OP_SETLIST: { // Lua.testAMode(Lua.OP_SETLIST) == false
|
|
||||||
if ( ((i>>14)&0x1ff) == 0 ) pc++; // if c == 0 then c stored in next op -> skip
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
if (Lua.testAMode(op) && reg == a) /* any instruction that set A */
|
if (Lua.testAMode(op) && reg == a) /* any instruction that set A */
|
||||||
setreg = pc;
|
setreg = pc;
|
||||||
|
|||||||
@@ -95,12 +95,6 @@ public class IoLib extends TwoArgFunction {
|
|||||||
// return number of bytes read if positive, false if eof, throw IOException on other exception
|
// return number of bytes read if positive, false if eof, throw IOException on other exception
|
||||||
abstract public int read(byte[] bytes, int offset, int length) throws IOException;
|
abstract public int read(byte[] bytes, int offset, int length) throws IOException;
|
||||||
|
|
||||||
public boolean eof() throws IOException {
|
|
||||||
try {
|
|
||||||
return peek() < 0;
|
|
||||||
} catch (EOFException e) { return true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// delegate method access to file methods table
|
// delegate method access to file methods table
|
||||||
public LuaValue get( LuaValue key ) {
|
public LuaValue get( LuaValue key ) {
|
||||||
return filemethods.get(key);
|
return filemethods.get(key);
|
||||||
@@ -118,18 +112,6 @@ public class IoLib extends TwoArgFunction {
|
|||||||
public String tojstring() {
|
public String tojstring() {
|
||||||
return "file: " + Integer.toHexString(hashCode());
|
return "file: " + Integer.toHexString(hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finalize() throws Throwable {
|
|
||||||
try {
|
|
||||||
if (!isclosed()) {
|
|
||||||
try {
|
|
||||||
close();
|
|
||||||
} catch (IOException ignore) {}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
super.finalize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Enumerated value representing stdin */
|
/** Enumerated value representing stdin */
|
||||||
@@ -274,7 +256,7 @@ public class IoLib extends TwoArgFunction {
|
|||||||
|
|
||||||
// return the table
|
// return the table
|
||||||
env.set("io", t);
|
env.set("io", t);
|
||||||
if (!env.get("package").isnil()) env.get("package").get("loaded").set("io", t);
|
env.get("package").get("loaded").set("io", t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,15 +269,8 @@ public class IoLib extends TwoArgFunction {
|
|||||||
static final class IoLibV extends VarArgFunction {
|
static final class IoLibV extends VarArgFunction {
|
||||||
private File f;
|
private File f;
|
||||||
public IoLib iolib;
|
public IoLib iolib;
|
||||||
private boolean toclose;
|
|
||||||
private Varargs args;
|
|
||||||
public IoLibV() {
|
public IoLibV() {
|
||||||
}
|
}
|
||||||
public IoLibV(File f, String name, int opcode, IoLib iolib, boolean toclose, Varargs args) {
|
|
||||||
this(f, name, opcode, iolib);
|
|
||||||
this.toclose = toclose;
|
|
||||||
this.args = args.dealias();
|
|
||||||
}
|
|
||||||
public IoLibV(File f, String name, int opcode, IoLib iolib) {
|
public IoLibV(File f, String name, int opcode, IoLib iolib) {
|
||||||
super();
|
super();
|
||||||
this.f = f;
|
this.f = f;
|
||||||
@@ -315,26 +290,22 @@ public class IoLib extends TwoArgFunction {
|
|||||||
case IO_TYPE: return iolib._io_type(args.arg1());
|
case IO_TYPE: return iolib._io_type(args.arg1());
|
||||||
case IO_POPEN: return iolib._io_popen(args.checkjstring(1),args.optjstring(2,"r"));
|
case IO_POPEN: return iolib._io_popen(args.checkjstring(1),args.optjstring(2,"r"));
|
||||||
case IO_OPEN: return iolib._io_open(args.checkjstring(1), args.optjstring(2,"r"));
|
case IO_OPEN: return iolib._io_open(args.checkjstring(1), args.optjstring(2,"r"));
|
||||||
case IO_LINES: return iolib._io_lines(args);
|
case IO_LINES: return iolib._io_lines(args.isvalue(1)? args.checkjstring(1): null);
|
||||||
case IO_READ: return iolib._io_read(args);
|
case IO_READ: return iolib._io_read(args);
|
||||||
case IO_WRITE: return iolib._io_write(args);
|
case IO_WRITE: return iolib._io_write(args);
|
||||||
|
|
||||||
case FILE_CLOSE: return iolib._file_close(args.arg1());
|
case FILE_CLOSE: return iolib._file_close(args.arg1());
|
||||||
case FILE_FLUSH: return iolib._file_flush(args.arg1());
|
case FILE_FLUSH: return iolib._file_flush(args.arg1());
|
||||||
case FILE_SETVBUF: return iolib._file_setvbuf(args.arg1(),args.checkjstring(2),args.optint(3,8192));
|
case FILE_SETVBUF: return iolib._file_setvbuf(args.arg1(),args.checkjstring(2),args.optint(3,1024));
|
||||||
case FILE_LINES: return iolib._file_lines(args);
|
case FILE_LINES: return iolib._file_lines(args.arg1());
|
||||||
case FILE_READ: return iolib._file_read(args.arg1(),args.subargs(2));
|
case FILE_READ: return iolib._file_read(args.arg1(),args.subargs(2));
|
||||||
case FILE_SEEK: return iolib._file_seek(args.arg1(),args.optjstring(2,"cur"),args.optint(3,0));
|
case FILE_SEEK: return iolib._file_seek(args.arg1(),args.optjstring(2,"cur"),args.optint(3,0));
|
||||||
case FILE_WRITE: return iolib._file_write(args.arg1(),args.subargs(2));
|
case FILE_WRITE: return iolib._file_write(args.arg1(),args.subargs(2));
|
||||||
|
|
||||||
case IO_INDEX: return iolib._io_index(args.arg(2));
|
case IO_INDEX: return iolib._io_index(args.arg(2));
|
||||||
case LINES_ITER: return iolib._lines_iter(f, toclose, this.args);
|
case LINES_ITER: return iolib._lines_iter(f);
|
||||||
}
|
}
|
||||||
} catch ( IOException ioe ) {
|
} catch ( IOException ioe ) {
|
||||||
if (opcode == LINES_ITER) {
|
|
||||||
String s = ioe.getMessage();
|
|
||||||
error(s != null ? s : ioe.toString());
|
|
||||||
}
|
|
||||||
return errorresult(ioe);
|
return errorresult(ioe);
|
||||||
}
|
}
|
||||||
return NONE;
|
return NONE;
|
||||||
@@ -390,7 +361,6 @@ public class IoLib extends TwoArgFunction {
|
|||||||
|
|
||||||
// io.popen(prog, [mode]) -> file
|
// io.popen(prog, [mode]) -> file
|
||||||
public Varargs _io_popen(String prog, String mode) throws IOException {
|
public Varargs _io_popen(String prog, String mode) throws IOException {
|
||||||
if (!"r".equals(mode) && !"w".equals(mode)) argerror(2, "invalid value: '" + mode + "'; must be one of 'r' or 'w'");
|
|
||||||
return openProgram(prog, mode);
|
return openProgram(prog, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,12 +369,11 @@ public class IoLib extends TwoArgFunction {
|
|||||||
return rawopenfile(FTYPE_NAMED, filename, mode);
|
return rawopenfile(FTYPE_NAMED, filename, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// io.lines(filename, ...) -> iterator
|
// io.lines(filename) -> iterator
|
||||||
public Varargs _io_lines(Varargs args) {
|
public Varargs _io_lines(String filename) {
|
||||||
String filename = args.optjstring(1, null);
|
infile = filename==null? input(): ioopenfile(FTYPE_NAMED, filename,"r");
|
||||||
File infile = filename==null? input(): ioopenfile(FTYPE_NAMED, filename,"r");
|
|
||||||
checkopen(infile);
|
checkopen(infile);
|
||||||
return lines(infile, filename != null, args.subargs(2));
|
return lines(infile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// io.read(...) -> (...)
|
// io.read(...) -> (...)
|
||||||
@@ -432,19 +401,13 @@ public class IoLib extends TwoArgFunction {
|
|||||||
|
|
||||||
// file:setvbuf(mode,[size]) -> void
|
// file:setvbuf(mode,[size]) -> void
|
||||||
public Varargs _file_setvbuf(LuaValue file, String mode, int size) {
|
public Varargs _file_setvbuf(LuaValue file, String mode, int size) {
|
||||||
if ("no".equals(mode)) {
|
|
||||||
} else if ("full".equals(mode)) {
|
|
||||||
} else if ("line".equals(mode)) {
|
|
||||||
} else {
|
|
||||||
argerror(1, "invalid value: '" + mode + "'; must be one of 'no', 'full' or 'line'");
|
|
||||||
}
|
|
||||||
checkfile(file).setvbuf(mode,size);
|
checkfile(file).setvbuf(mode,size);
|
||||||
return LuaValue.TRUE;
|
return LuaValue.TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// file:lines(...) -> iterator
|
// file:lines() -> iterator
|
||||||
public Varargs _file_lines(Varargs args) {
|
public Varargs _file_lines(LuaValue file) {
|
||||||
return lines(checkfile(args.arg1()), false, args.subargs(2));
|
return lines(checkfile(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
// file:read(...) -> (...)
|
// file:read(...) -> (...)
|
||||||
@@ -454,12 +417,6 @@ public class IoLib extends TwoArgFunction {
|
|||||||
|
|
||||||
// file:seek([whence][,offset]) -> pos | nil,error
|
// file:seek([whence][,offset]) -> pos | nil,error
|
||||||
public Varargs _file_seek(LuaValue file, String whence, int offset) throws IOException {
|
public Varargs _file_seek(LuaValue file, String whence, int offset) throws IOException {
|
||||||
if ("set".equals(whence)) {
|
|
||||||
} else if ("end".equals(whence)) {
|
|
||||||
} else if ("cur".equals(whence)) {
|
|
||||||
} else {
|
|
||||||
argerror(1, "invalid value: '" + whence + "'; must be one of 'set', 'cur' or 'end'");
|
|
||||||
}
|
|
||||||
return valueOf( checkfile(file).seek(whence,offset) );
|
return valueOf( checkfile(file).seek(whence,offset) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,13 +433,8 @@ public class IoLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lines iterator(s,var) -> var'
|
// lines iterator(s,var) -> var'
|
||||||
public Varargs _lines_iter(LuaValue file, boolean toclose, Varargs args) throws IOException {
|
public Varargs _lines_iter(LuaValue file) throws IOException {
|
||||||
File f = optfile(file);
|
return freadline(checkfile(file));
|
||||||
if ( f == null ) argerror(1, "not a file: " + file);
|
|
||||||
if ( f.isclosed() ) error("file is already closed");
|
|
||||||
Varargs ret = ioread(f, args);
|
|
||||||
if (toclose && ret.isnil(1) && f.eof()) f.close();
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private File output() {
|
private File output() {
|
||||||
@@ -515,7 +467,7 @@ public class IoLib extends TwoArgFunction {
|
|||||||
return LuaValue.TRUE;
|
return LuaValue.TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Varargs errorresult(Exception ioe) {
|
private static Varargs errorresult(Exception ioe) {
|
||||||
String s = ioe.getMessage();
|
String s = ioe.getMessage();
|
||||||
return errorresult("io error: "+(s!=null? s: ioe.toString()));
|
return errorresult("io error: "+(s!=null? s: ioe.toString()));
|
||||||
}
|
}
|
||||||
@@ -524,9 +476,9 @@ public class IoLib extends TwoArgFunction {
|
|||||||
return varargsOf(NIL, valueOf(errortext));
|
return varargsOf(NIL, valueOf(errortext));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Varargs lines(final File f, boolean toclose, Varargs args) {
|
private Varargs lines(final File f) {
|
||||||
try {
|
try {
|
||||||
return new IoLibV(f,"lnext",LINES_ITER,this,toclose,args);
|
return new IoLibV(f,"lnext",LINES_ITER,this);
|
||||||
} catch ( Exception e ) {
|
} catch ( Exception e ) {
|
||||||
return error("lines: "+e);
|
return error("lines: "+e);
|
||||||
}
|
}
|
||||||
@@ -540,7 +492,6 @@ public class IoLib extends TwoArgFunction {
|
|||||||
|
|
||||||
private Varargs ioread(File f, Varargs args) throws IOException {
|
private Varargs ioread(File f, Varargs args) throws IOException {
|
||||||
int i,n=args.narg();
|
int i,n=args.narg();
|
||||||
if (n == 0) return freadline(f,false);
|
|
||||||
LuaValue[] v = new LuaValue[n];
|
LuaValue[] v = new LuaValue[n];
|
||||||
LuaValue ai,vi;
|
LuaValue ai,vi;
|
||||||
LuaString fmt;
|
LuaString fmt;
|
||||||
@@ -551,11 +502,10 @@ public class IoLib extends TwoArgFunction {
|
|||||||
break item;
|
break item;
|
||||||
case LuaValue.TSTRING:
|
case LuaValue.TSTRING:
|
||||||
fmt = ai.checkstring();
|
fmt = ai.checkstring();
|
||||||
if ( fmt.m_length >= 2 && fmt.m_bytes[fmt.m_offset] == '*' ) {
|
if ( fmt.m_length == 2 && fmt.m_bytes[fmt.m_offset] == '*' ) {
|
||||||
switch ( fmt.m_bytes[fmt.m_offset+1] ) {
|
switch ( fmt.m_bytes[fmt.m_offset+1] ) {
|
||||||
case 'n': vi = freadnumber(f); break item;
|
case 'n': vi = freadnumber(f); break item;
|
||||||
case 'l': vi = freadline(f,false); break item;
|
case 'l': vi = freadline(f); break item;
|
||||||
case 'L': vi = freadline(f,true); break item;
|
|
||||||
case 'a': vi = freadall(f); break item;
|
case 'a': vi = freadall(f); break item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -587,17 +537,6 @@ public class IoLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private File rawopenfile(int filetype, String filename, String mode) throws IOException {
|
private File rawopenfile(int filetype, String filename, String mode) throws IOException {
|
||||||
int len = mode.length();
|
|
||||||
for (int i = 0; i < len; i++) { // [rwa][+]?b*
|
|
||||||
char ch = mode.charAt(i);
|
|
||||||
if (i == 0 && "rwa".indexOf(ch) >= 0) continue;
|
|
||||||
if (i == 1 && ch == '+') continue;
|
|
||||||
if (i >= 1 && ch == 'b') continue;
|
|
||||||
len = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (len <= 0) argerror(2, "invalid mode: '" + mode + "'");
|
|
||||||
|
|
||||||
switch (filetype) {
|
switch (filetype) {
|
||||||
case FTYPE_STDIN: return wrapStdin();
|
case FTYPE_STDIN: return wrapStdin();
|
||||||
case FTYPE_STDOUT: return wrapStdout();
|
case FTYPE_STDOUT: return wrapStdout();
|
||||||
@@ -605,7 +544,7 @@ public class IoLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
boolean isreadmode = mode.startsWith("r");
|
boolean isreadmode = mode.startsWith("r");
|
||||||
boolean isappend = mode.startsWith("a");
|
boolean isappend = mode.startsWith("a");
|
||||||
boolean isupdate = mode.indexOf('+') > 0;
|
boolean isupdate = mode.indexOf("+") > 0;
|
||||||
boolean isbinary = mode.endsWith("b");
|
boolean isbinary = mode.endsWith("b");
|
||||||
return openFile( filename, isreadmode, isappend, isupdate, isbinary );
|
return openFile( filename, isreadmode, isappend, isupdate, isbinary );
|
||||||
}
|
}
|
||||||
@@ -614,27 +553,26 @@ public class IoLib extends TwoArgFunction {
|
|||||||
// ------------- file reading utilitied ------------------
|
// ------------- file reading utilitied ------------------
|
||||||
|
|
||||||
public static LuaValue freadbytes(File f, int count) throws IOException {
|
public static LuaValue freadbytes(File f, int count) throws IOException {
|
||||||
if (count == 0) return f.eof() ? NIL : EMPTYSTRING;
|
|
||||||
byte[] b = new byte[count];
|
byte[] b = new byte[count];
|
||||||
int r;
|
int r;
|
||||||
if ( ( r = f.read(b,0,b.length) ) < 0 )
|
if ( ( r = f.read(b,0,b.length) ) < 0 )
|
||||||
return NIL;
|
return NIL;
|
||||||
return LuaString.valueUsing(b, 0, r);
|
return LuaString.valueUsing(b, 0, r);
|
||||||
}
|
}
|
||||||
public static LuaValue freaduntil(File f,boolean lineonly,boolean withend) throws IOException {
|
public static LuaValue freaduntil(File f,boolean lineonly) throws IOException {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
int c;
|
int c;
|
||||||
try {
|
try {
|
||||||
if ( lineonly ) {
|
if ( lineonly ) {
|
||||||
loop: while ( (c = f.read()) >= 0 ) {
|
loop: while ( (c = f.read()) > 0 ) {
|
||||||
switch ( c ) {
|
switch ( c ) {
|
||||||
case '\r': if (withend) baos.write(c); break;
|
case '\r': break;
|
||||||
case '\n': if (withend) baos.write(c); break loop;
|
case '\n': break loop;
|
||||||
default: baos.write(c); break;
|
default: baos.write(c); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while ( (c = f.read()) >= 0 )
|
while ( (c = f.read()) > 0 )
|
||||||
baos.write(c);
|
baos.write(c);
|
||||||
}
|
}
|
||||||
} catch ( EOFException e ) {
|
} catch ( EOFException e ) {
|
||||||
@@ -644,15 +582,15 @@ public class IoLib extends TwoArgFunction {
|
|||||||
(LuaValue) NIL:
|
(LuaValue) NIL:
|
||||||
(LuaValue) LuaString.valueUsing(baos.toByteArray());
|
(LuaValue) LuaString.valueUsing(baos.toByteArray());
|
||||||
}
|
}
|
||||||
public static LuaValue freadline(File f,boolean withend) throws IOException {
|
public static LuaValue freadline(File f) throws IOException {
|
||||||
return freaduntil(f,true,withend);
|
return freaduntil(f,true);
|
||||||
}
|
}
|
||||||
public static LuaValue freadall(File f) throws IOException {
|
public static LuaValue freadall(File f) throws IOException {
|
||||||
int n = f.remaining();
|
int n = f.remaining();
|
||||||
if ( n >= 0 ) {
|
if ( n >= 0 ) {
|
||||||
return n == 0 ? EMPTYSTRING : freadbytes(f, n);
|
return freadbytes(f, n);
|
||||||
} else {
|
} else {
|
||||||
return freaduntil(f,false,false);
|
return freaduntil(f,false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static LuaValue freadnumber(File f) throws IOException {
|
public static LuaValue freadnumber(File f) throws IOException {
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ abstract public class LibFunction extends LuaFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String tojstring() {
|
public String tojstring() {
|
||||||
return name != null ? "function: " + name : super.tojstring();
|
return name != null? name: super.tojstring();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -196,7 +196,7 @@ abstract public class LibFunction extends LuaFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LuaValue call() {
|
public LuaValue call() {
|
||||||
return argerror(1,"value expected");
|
return argerror(1,"value");
|
||||||
}
|
}
|
||||||
public LuaValue call(LuaValue a) {
|
public LuaValue call(LuaValue a) {
|
||||||
return call();
|
return call();
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ public class MathLib extends TwoArgFunction {
|
|||||||
math.set("sqrt", new sqrt());
|
math.set("sqrt", new sqrt());
|
||||||
math.set("tan", new tan());
|
math.set("tan", new tan());
|
||||||
env.set("math", math);
|
env.set("math", math);
|
||||||
if (!env.get("package").isnil()) env.get("package").get("loaded").set("math", math);
|
env.get("package").get("loaded").set("math", math);
|
||||||
return math;
|
return math;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,12 +163,10 @@ public class MathLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class fmod extends TwoArgFunction {
|
static final class fmod extends BinaryOp {
|
||||||
public LuaValue call(LuaValue xv, LuaValue yv) {
|
protected double call(double x, double y) {
|
||||||
if (xv.islong() && yv.islong()) {
|
double q = x/y;
|
||||||
return valueOf(xv.tolong() % yv.tolong());
|
return x - y * (q>=0? Math.floor(q): Math.ceil(q));
|
||||||
}
|
|
||||||
return valueOf(xv.checkdouble() % yv.checkdouble());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static final class ldexp extends BinaryOp {
|
static final class ldexp extends BinaryOp {
|
||||||
@@ -196,36 +194,27 @@ public class MathLib extends TwoArgFunction {
|
|||||||
|
|
||||||
static class max extends VarArgFunction {
|
static class max extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaValue m = args.checkvalue(1);
|
double m = args.checkdouble(1);
|
||||||
for ( int i=2,n=args.narg(); i<=n; ++i ) {
|
for ( int i=2,n=args.narg(); i<=n; ++i )
|
||||||
LuaValue v = args.checkvalue(i);
|
m = Math.max(m,args.checkdouble(i));
|
||||||
if (m.lt_b(v)) m = v;
|
return valueOf(m);
|
||||||
}
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class min extends VarArgFunction {
|
static class min extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaValue m = args.checkvalue(1);
|
double m = args.checkdouble(1);
|
||||||
for ( int i=2,n=args.narg(); i<=n; ++i ) {
|
for ( int i=2,n=args.narg(); i<=n; ++i )
|
||||||
LuaValue v = args.checkvalue(i);
|
m = Math.min(m,args.checkdouble(i));
|
||||||
if (v.lt_b(m)) m = v;
|
return valueOf(m);
|
||||||
}
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class modf extends VarArgFunction {
|
static class modf extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaValue n = args.arg1();
|
double x = args.checkdouble(1);
|
||||||
/* 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 intPart = ( x > 0 ) ? Math.floor( x ) : Math.ceil( x );
|
||||||
/* fractional part (test needed for inf/-inf) */
|
double fracPart = x - intPart;
|
||||||
double fracPart = x == intPart ? 0.0 : x - intPart;
|
|
||||||
return varargsOf( valueOf(intPart), valueOf(fracPart) );
|
return varargsOf( valueOf(intPart), valueOf(fracPart) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ import org.luaj.vm2.Varargs;
|
|||||||
* @see <a href="http://www.lua.org/manual/5.1/manual.html#5.8">http://www.lua.org/manual/5.1/manual.html#5.8</a>
|
* @see <a href="http://www.lua.org/manual/5.1/manual.html#5.8">http://www.lua.org/manual/5.1/manual.html#5.8</a>
|
||||||
*/
|
*/
|
||||||
public class OsLib extends TwoArgFunction {
|
public class OsLib extends TwoArgFunction {
|
||||||
public static final String TMP_PREFIX = ".luaj";
|
public static String TMP_PREFIX = ".luaj";
|
||||||
public static final String TMP_SUFFIX = "tmp";
|
public static String TMP_SUFFIX = "tmp";
|
||||||
|
|
||||||
private static final int CLOCK = 0;
|
private static final int CLOCK = 0;
|
||||||
private static final int DATE = 1;
|
private static final int DATE = 1;
|
||||||
@@ -132,7 +132,7 @@ public class OsLib extends TwoArgFunction {
|
|||||||
for (int i = 0; i < NAMES.length; ++i)
|
for (int i = 0; i < NAMES.length; ++i)
|
||||||
os.set(NAMES[i], new OsLibFunc(i, NAMES[i]));
|
os.set(NAMES[i], new OsLibFunc(i, NAMES[i]));
|
||||||
env.set("os", os);
|
env.set("os", os);
|
||||||
if (!env.get("package").isnil()) env.get("package").get("loaded").set("os", os);
|
env.get("package").get("loaded").set("os", os);
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,26 +81,23 @@ public class PackageLib extends TwoArgFunction {
|
|||||||
|
|
||||||
/** The default value to use for package.path. This can be set with the system property
|
/** The default value to use for package.path. This can be set with the system property
|
||||||
* <code>"luaj.package.path"</code>, and is <code>"?.lua"</code> by default. */
|
* <code>"luaj.package.path"</code>, and is <code>"?.lua"</code> by default. */
|
||||||
public static final String DEFAULT_LUA_PATH;
|
public static String DEFAULT_LUA_PATH;
|
||||||
static {
|
static {
|
||||||
String path = null;
|
|
||||||
try {
|
try {
|
||||||
path = System.getProperty("luaj.package.path");
|
DEFAULT_LUA_PATH = System.getProperty("luaj.package.path");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println(e.toString());
|
System.out.println(e.toString());
|
||||||
}
|
}
|
||||||
if (path == null) {
|
if (DEFAULT_LUA_PATH == null)
|
||||||
path = "?.lua";
|
DEFAULT_LUA_PATH = "?.lua";
|
||||||
}
|
|
||||||
DEFAULT_LUA_PATH = path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static final LuaString _LOADED = valueOf("loaded");
|
private static final LuaString _LOADED = valueOf("loaded");
|
||||||
private static final LuaString _LOADLIB = valueOf("loadlib");
|
private static final LuaString _LOADLIB = valueOf("loadlib");
|
||||||
static final LuaString _PRELOAD = valueOf("preload");
|
private static final LuaString _PRELOAD = valueOf("preload");
|
||||||
static final LuaString _PATH = valueOf("path");
|
private static final LuaString _PATH = valueOf("path");
|
||||||
static final LuaString _SEARCHPATH = valueOf("searchpath");
|
private static final LuaString _SEARCHPATH = valueOf("searchpath");
|
||||||
static final LuaString _SEARCHERS = valueOf("searchers");
|
private static final LuaString _SEARCHERS = valueOf("searchers");
|
||||||
|
|
||||||
/** The globals that were used to load this library. */
|
/** The globals that were used to load this library. */
|
||||||
Globals globals;
|
Globals globals;
|
||||||
@@ -144,7 +141,6 @@ public class PackageLib extends TwoArgFunction {
|
|||||||
searchers.set(2, lua_searcher = new lua_searcher());
|
searchers.set(2, lua_searcher = new lua_searcher());
|
||||||
searchers.set(3, java_searcher = new java_searcher());
|
searchers.set(3, java_searcher = new java_searcher());
|
||||||
package_.set(_SEARCHERS, searchers);
|
package_.set(_SEARCHERS, searchers);
|
||||||
package_.set("config", FILE_SEP + "\n;\n?\n!\n-\n");
|
|
||||||
package_.get(_LOADED).set("package", package_);
|
package_.get(_LOADED).set("package", package_);
|
||||||
env.set("package", package_);
|
env.set("package", package_);
|
||||||
globals.package_ = this;
|
globals.package_ = this;
|
||||||
@@ -237,7 +233,7 @@ public class PackageLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class loadlib extends VarArgFunction {
|
public static class loadlib extends VarArgFunction {
|
||||||
public Varargs invoke( Varargs args ) {
|
public Varargs loadlib( Varargs args ) {
|
||||||
args.checkstring(1);
|
args.checkstring(1);
|
||||||
return varargsOf(NIL, valueOf("dynamic libraries not enabled"), valueOf("absent"));
|
return varargsOf(NIL, valueOf("dynamic libraries not enabled"), valueOf("absent"));
|
||||||
}
|
}
|
||||||
@@ -256,6 +252,7 @@ public class PackageLib extends TwoArgFunction {
|
|||||||
public class lua_searcher extends VarArgFunction {
|
public class lua_searcher extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaString name = args.checkstring(1);
|
LuaString name = args.checkstring(1);
|
||||||
|
InputStream is = null;
|
||||||
|
|
||||||
// get package path
|
// get package path
|
||||||
LuaValue path = package_.get(_PATH);
|
LuaValue path = package_.get(_PATH);
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ package org.luaj.vm2.lib;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.luaj.vm2.Buffer;
|
|
||||||
import org.luaj.vm2.LuaClosure;
|
import org.luaj.vm2.LuaClosure;
|
||||||
|
import org.luaj.vm2.Buffer;
|
||||||
import org.luaj.vm2.LuaString;
|
import org.luaj.vm2.LuaString;
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.LuaTable;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
@@ -49,7 +49,7 @@ import org.luaj.vm2.compiler.DumpState;
|
|||||||
* Globals globals = new Globals();
|
* Globals globals = new Globals();
|
||||||
* globals.load(new JseBaseLib());
|
* globals.load(new JseBaseLib());
|
||||||
* globals.load(new PackageLib());
|
* globals.load(new PackageLib());
|
||||||
* globals.load(new JseStringLib());
|
* globals.load(new StringLib());
|
||||||
* System.out.println( globals.get("string").get("upper").call( LuaValue.valueOf("abcde") ) );
|
* System.out.println( globals.get("string").get("upper").call( LuaValue.valueOf("abcde") ) );
|
||||||
* } </pre>
|
* } </pre>
|
||||||
* <p>
|
* <p>
|
||||||
@@ -83,8 +83,8 @@ public class StringLib extends TwoArgFunction {
|
|||||||
*/
|
*/
|
||||||
public LuaValue call(LuaValue modname, LuaValue env) {
|
public LuaValue call(LuaValue modname, LuaValue env) {
|
||||||
LuaTable string = new LuaTable();
|
LuaTable string = new LuaTable();
|
||||||
string.set("byte", new _byte());
|
string.set("byte", new byte_());
|
||||||
string.set("char", new _char());
|
string.set("char", new char_());
|
||||||
string.set("dump", new dump());
|
string.set("dump", new dump());
|
||||||
string.set("find", new find());
|
string.set("find", new find());
|
||||||
string.set("format", new format());
|
string.set("format", new format());
|
||||||
@@ -97,12 +97,12 @@ public class StringLib extends TwoArgFunction {
|
|||||||
string.set("reverse", new reverse());
|
string.set("reverse", new reverse());
|
||||||
string.set("sub", new sub());
|
string.set("sub", new sub());
|
||||||
string.set("upper", new upper());
|
string.set("upper", new upper());
|
||||||
|
LuaTable mt = LuaValue.tableOf(
|
||||||
|
new LuaValue[] { INDEX, string });
|
||||||
env.set("string", string);
|
env.set("string", string);
|
||||||
if (!env.get("package").isnil()) env.get("package").get("loaded").set("string", string);
|
env.get("package").get("loaded").set("string", string);
|
||||||
if (LuaString.s_metatable == null) {
|
if (LuaString.s_metatable == null)
|
||||||
LuaString.s_metatable = LuaValue.tableOf(new LuaValue[] { INDEX, string });
|
LuaString.s_metatable = mt;
|
||||||
}
|
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ public class StringLib extends TwoArgFunction {
|
|||||||
*
|
*
|
||||||
* @param args the calling args
|
* @param args the calling args
|
||||||
*/
|
*/
|
||||||
static final class _byte extends VarArgFunction {
|
static final class byte_ extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaString s = args.checkstring(1);
|
LuaString s = args.checkstring(1);
|
||||||
int l = s.m_length;
|
int l = s.m_length;
|
||||||
@@ -148,13 +148,13 @@ public class StringLib extends TwoArgFunction {
|
|||||||
*
|
*
|
||||||
* @param args the calling VM
|
* @param args the calling VM
|
||||||
*/
|
*/
|
||||||
static final class _char extends VarArgFunction {
|
static final class char_ extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
int n = args.narg();
|
int n = args.narg();
|
||||||
byte[] bytes = new byte[n];
|
byte[] bytes = new byte[n];
|
||||||
for ( int i=0, a=1; i<n; i++, a++ ) {
|
for ( int i=0, a=1; i<n; i++, a++ ) {
|
||||||
int c = args.checkint(a);
|
int c = args.checkint(a);
|
||||||
if (c<0 || c>=256) argerror(a, "invalid value for string.char [0; 255]: " + c);
|
if (c<0 || c>=256) argerror(a, "invalid value");
|
||||||
bytes[i] = (byte) c;
|
bytes[i] = (byte) c;
|
||||||
}
|
}
|
||||||
return LuaString.valueUsing( bytes );
|
return LuaString.valueUsing( bytes );
|
||||||
@@ -162,22 +162,20 @@ public class StringLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* string.dump (function[, stripDebug])
|
* string.dump (function)
|
||||||
*
|
*
|
||||||
* Returns a string containing a binary representation of the given function,
|
* Returns a string containing a binary representation of the given function,
|
||||||
* so that a later loadstring on this string returns a copy of the function.
|
* so that a later loadstring on this string returns a copy of the function.
|
||||||
* function must be a Lua function without upvalues.
|
* function must be a Lua function without upvalues.
|
||||||
* Boolean param stripDebug - true to strip debugging info, false otherwise.
|
|
||||||
* The default value for stripDebug is true.
|
|
||||||
*
|
*
|
||||||
* TODO: port dumping code as optional add-on
|
* TODO: port dumping code as optional add-on
|
||||||
*/
|
*/
|
||||||
static final class dump extends VarArgFunction {
|
static final class dump extends OneArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public LuaValue call(LuaValue arg) {
|
||||||
LuaValue f = args.checkfunction(1);
|
LuaValue f = arg.checkfunction();
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
try {
|
try {
|
||||||
DumpState.dump( ((LuaClosure)f).p, baos, args.optboolean(2, true) );
|
DumpState.dump( ((LuaClosure)f).p, baos, true );
|
||||||
return LuaString.valueUsing(baos.toByteArray());
|
return LuaString.valueUsing(baos.toByteArray());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return error( e.getMessage() );
|
return error( e.getMessage() );
|
||||||
@@ -230,7 +228,7 @@ public class StringLib extends TwoArgFunction {
|
|||||||
* This function does not accept string values containing embedded zeros,
|
* This function does not accept string values containing embedded zeros,
|
||||||
* except as arguments to the q option.
|
* except as arguments to the q option.
|
||||||
*/
|
*/
|
||||||
final class format extends VarArgFunction {
|
static final class format extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaString fmt = args.checkstring( 1 );
|
LuaString fmt = args.checkstring( 1 );
|
||||||
final int n = fmt.length();
|
final int n = fmt.length();
|
||||||
@@ -261,7 +259,7 @@ public class StringLib extends TwoArgFunction {
|
|||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'd':
|
case 'd':
|
||||||
fdsc.format( result, args.checklong( arg ) );
|
fdsc.format( result, args.checkint( arg ) );
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
case 'u':
|
case 'u':
|
||||||
@@ -300,7 +298,7 @@ public class StringLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addquoted(Buffer buf, LuaString s) {
|
private static void addquoted(Buffer buf, LuaString s) {
|
||||||
int c;
|
int c;
|
||||||
buf.append( (byte) '"' );
|
buf.append( (byte) '"' );
|
||||||
for ( int i = 0, n = s.length(); i < n; i++ ) {
|
for ( int i = 0, n = s.length(); i < n; i++ ) {
|
||||||
@@ -330,7 +328,7 @@ public class StringLib extends TwoArgFunction {
|
|||||||
|
|
||||||
private static final String FLAGS = "-+ #0";
|
private static final String FLAGS = "-+ #0";
|
||||||
|
|
||||||
class FormatDesc {
|
static class FormatDesc {
|
||||||
|
|
||||||
private boolean leftAdjust;
|
private boolean leftAdjust;
|
||||||
private boolean zeroPad;
|
private boolean zeroPad;
|
||||||
@@ -340,13 +338,11 @@ public class StringLib extends TwoArgFunction {
|
|||||||
private static final int MAX_FLAGS = 5;
|
private static final int MAX_FLAGS = 5;
|
||||||
|
|
||||||
private int width;
|
private int width;
|
||||||
int precision;
|
private int precision;
|
||||||
|
|
||||||
public final int conversion;
|
public final int conversion;
|
||||||
public final int length;
|
public final int length;
|
||||||
|
|
||||||
public final String src;
|
|
||||||
|
|
||||||
public FormatDesc(Varargs args, LuaString strfrmt, final int start) {
|
public FormatDesc(Varargs args, LuaString strfrmt, final int start) {
|
||||||
int p = start, n = strfrmt.length();
|
int p = start, n = strfrmt.length();
|
||||||
int c = 0;
|
int c = 0;
|
||||||
@@ -394,7 +390,6 @@ public class StringLib extends TwoArgFunction {
|
|||||||
zeroPad &= !leftAdjust; // '-' overrides '0'
|
zeroPad &= !leftAdjust; // '-' overrides '0'
|
||||||
conversion = c;
|
conversion = c;
|
||||||
length = p - start;
|
length = p - start;
|
||||||
src = strfrmt.substring(start - 1, p).tojstring();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void format(Buffer buf, byte c) {
|
public void format(Buffer buf, byte c) {
|
||||||
@@ -470,7 +465,8 @@ public class StringLib extends TwoArgFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void format(Buffer buf, double x) {
|
public void format(Buffer buf, double x) {
|
||||||
buf.append( StringLib.this.format(src, x) );
|
// TODO
|
||||||
|
buf.append( String.valueOf( x ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void format(Buffer buf, LuaString s) {
|
public void format(Buffer buf, LuaString s) {
|
||||||
@@ -480,17 +476,13 @@ public class StringLib extends TwoArgFunction {
|
|||||||
buf.append(s);
|
buf.append(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void pad(Buffer buf, char c, int n) {
|
public static final void pad(Buffer buf, char c, int n) {
|
||||||
byte b = (byte)c;
|
byte b = (byte)c;
|
||||||
while ( n-- > 0 )
|
while ( n-- > 0 )
|
||||||
buf.append(b);
|
buf.append(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String format(String src, double x) {
|
|
||||||
return String.valueOf(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* string.gmatch (s, pattern)
|
* string.gmatch (s, pattern)
|
||||||
*
|
*
|
||||||
@@ -527,20 +519,18 @@ public class StringLib extends TwoArgFunction {
|
|||||||
private final int srclen;
|
private final int srclen;
|
||||||
private final MatchState ms;
|
private final MatchState ms;
|
||||||
private int soffset;
|
private int soffset;
|
||||||
private int lastmatch;
|
|
||||||
public GMatchAux(Varargs args, LuaString src, LuaString pat) {
|
public GMatchAux(Varargs args, LuaString src, LuaString pat) {
|
||||||
this.srclen = src.length();
|
this.srclen = src.length();
|
||||||
this.ms = new MatchState(args, src, pat);
|
this.ms = new MatchState(args, src, pat);
|
||||||
this.soffset = 0;
|
this.soffset = 0;
|
||||||
this.lastmatch = -1;
|
|
||||||
}
|
}
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
for ( ; soffset<=srclen; soffset++ ) {
|
for ( ; soffset<srclen; soffset++ ) {
|
||||||
ms.reset();
|
ms.reset();
|
||||||
int res = ms.match(soffset, 0);
|
int res = ms.match(soffset, 0);
|
||||||
if ( res >=0 && res != lastmatch ) {
|
if ( res >=0 ) {
|
||||||
int soff = soffset;
|
int soff = soffset;
|
||||||
lastmatch = soffset = res;
|
soffset = res;
|
||||||
return ms.push_captures( true, soff, res );
|
return ms.push_captures( true, soff, res );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -599,7 +589,6 @@ public class StringLib extends TwoArgFunction {
|
|||||||
LuaString src = args.checkstring( 1 );
|
LuaString src = args.checkstring( 1 );
|
||||||
final int srclen = src.length();
|
final int srclen = src.length();
|
||||||
LuaString p = args.checkstring( 2 );
|
LuaString p = args.checkstring( 2 );
|
||||||
int lastmatch = -1; /* end of last match */
|
|
||||||
LuaValue repl = args.arg( 3 );
|
LuaValue repl = args.arg( 3 );
|
||||||
int max_s = args.optint( 4, srclen + 1 );
|
int max_s = args.optint( 4, srclen + 1 );
|
||||||
final boolean anchor = p.length() > 0 && p.charAt( 0 ) == '^';
|
final boolean anchor = p.length() > 0 && p.charAt( 0 ) == '^';
|
||||||
@@ -612,15 +601,18 @@ public class StringLib extends TwoArgFunction {
|
|||||||
while ( n < max_s ) {
|
while ( n < max_s ) {
|
||||||
ms.reset();
|
ms.reset();
|
||||||
int res = ms.match( soffset, anchor ? 1 : 0 );
|
int res = ms.match( soffset, anchor ? 1 : 0 );
|
||||||
if ( res != -1 && res != lastmatch ) { /* match? */
|
if ( res != -1 ) {
|
||||||
n++;
|
n++;
|
||||||
ms.add_value( lbuf, soffset, res, repl ); /* add replacement to buffer */
|
ms.add_value( lbuf, soffset, res, repl );
|
||||||
soffset = lastmatch = res;
|
|
||||||
}
|
}
|
||||||
else if ( soffset < srclen ) /* otherwise, skip one character */
|
if ( res != -1 && res > soffset )
|
||||||
|
soffset = res;
|
||||||
|
else if ( soffset < srclen )
|
||||||
lbuf.append( (byte) src.luaByte( soffset++ ) );
|
lbuf.append( (byte) src.luaByte( soffset++ ) );
|
||||||
else break; /* end of subject */
|
else
|
||||||
if ( anchor ) break;
|
break;
|
||||||
|
if ( anchor )
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
lbuf.append( src.substring( soffset, srclen ) );
|
lbuf.append( src.substring( soffset, srclen ) );
|
||||||
return varargsOf(lbuf.tostring(), valueOf(n));
|
return varargsOf(lbuf.tostring(), valueOf(n));
|
||||||
@@ -772,7 +764,7 @@ public class StringLib extends TwoArgFunction {
|
|||||||
|
|
||||||
boolean anchor = false;
|
boolean anchor = false;
|
||||||
int poff = 0;
|
int poff = 0;
|
||||||
if ( pat.length() > 0 && pat.luaByte( 0 ) == '^' ) {
|
if ( pat.luaByte( 0 ) == '^' ) {
|
||||||
anchor = true;
|
anchor = true;
|
||||||
poff = 1;
|
poff = 1;
|
||||||
}
|
}
|
||||||
@@ -793,7 +785,7 @@ public class StringLib extends TwoArgFunction {
|
|||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int posrelat( int pos, int len ) {
|
private static int posrelat( int pos, int len ) {
|
||||||
return ( pos >= 0 ) ? pos : len + pos + 1;
|
return ( pos >= 0 ) ? pos : len + pos + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,8 +795,6 @@ public class StringLib extends TwoArgFunction {
|
|||||||
private static final LuaString SPECIALS = valueOf("^$*+?.([%-");
|
private static final LuaString SPECIALS = valueOf("^$*+?.([%-");
|
||||||
private static final int MAX_CAPTURES = 32;
|
private static final int MAX_CAPTURES = 32;
|
||||||
|
|
||||||
private static final int MAXCCALLS = 200;
|
|
||||||
|
|
||||||
private static final int CAP_UNFINISHED = -1;
|
private static final int CAP_UNFINISHED = -1;
|
||||||
private static final int CAP_POSITION = -2;
|
private static final int CAP_POSITION = -2;
|
||||||
|
|
||||||
@@ -817,12 +807,12 @@ public class StringLib extends TwoArgFunction {
|
|||||||
private static final byte MASK_CONTROL = 0x40;
|
private static final byte MASK_CONTROL = 0x40;
|
||||||
private static final byte MASK_HEXDIGIT = (byte)0x80;
|
private static final byte MASK_HEXDIGIT = (byte)0x80;
|
||||||
|
|
||||||
static final byte[] CHAR_TABLE;
|
private static final byte[] CHAR_TABLE;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
CHAR_TABLE = new byte[256];
|
CHAR_TABLE = new byte[256];
|
||||||
|
|
||||||
for ( int i = 0; i < 128; ++i ) {
|
for ( int i = 0; i < 256; ++i ) {
|
||||||
final char c = (char) i;
|
final char c = (char) i;
|
||||||
CHAR_TABLE[i] = (byte)( ( Character.isDigit( c ) ? MASK_DIGIT : 0 ) |
|
CHAR_TABLE[i] = (byte)( ( Character.isDigit( c ) ? MASK_DIGIT : 0 ) |
|
||||||
( Character.isLowerCase( c ) ? MASK_LOWERCASE : 0 ) |
|
( Character.isLowerCase( c ) ? MASK_LOWERCASE : 0 ) |
|
||||||
@@ -831,7 +821,7 @@ public class StringLib extends TwoArgFunction {
|
|||||||
if ( ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) || ( c >= '0' && c <= '9' ) ) {
|
if ( ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) || ( c >= '0' && c <= '9' ) ) {
|
||||||
CHAR_TABLE[i] |= MASK_HEXDIGIT;
|
CHAR_TABLE[i] |= MASK_HEXDIGIT;
|
||||||
}
|
}
|
||||||
if ( ( c >= '!' && c <= '/' ) || ( c >= ':' && c <= '@' ) || ( c >= '[' && c <= '`' ) || ( c >= '{' && c <= '~' ) ) {
|
if ( ( c >= '!' && c <= '/' ) || ( c >= ':' && c <= '@' ) ) {
|
||||||
CHAR_TABLE[i] |= MASK_PUNCT;
|
CHAR_TABLE[i] |= MASK_PUNCT;
|
||||||
}
|
}
|
||||||
if ( ( CHAR_TABLE[i] & ( MASK_LOWERCASE | MASK_UPPERCASE ) ) != 0 ) {
|
if ( ( CHAR_TABLE[i] & ( MASK_LOWERCASE | MASK_UPPERCASE ) ) != 0 ) {
|
||||||
@@ -843,12 +833,11 @@ public class StringLib extends TwoArgFunction {
|
|||||||
CHAR_TABLE['\r'] |= MASK_SPACE;
|
CHAR_TABLE['\r'] |= MASK_SPACE;
|
||||||
CHAR_TABLE['\n'] |= MASK_SPACE;
|
CHAR_TABLE['\n'] |= MASK_SPACE;
|
||||||
CHAR_TABLE['\t'] |= MASK_SPACE;
|
CHAR_TABLE['\t'] |= MASK_SPACE;
|
||||||
CHAR_TABLE[0x0B /* '\v' */ ] |= MASK_SPACE;
|
CHAR_TABLE[0x0C /* '\v' */ ] |= MASK_SPACE;
|
||||||
CHAR_TABLE['\f'] |= MASK_SPACE;
|
CHAR_TABLE['\f'] |= MASK_SPACE;
|
||||||
};
|
};
|
||||||
|
|
||||||
static class MatchState {
|
static class MatchState {
|
||||||
int matchdepth; /* control for recursive depth (to avoid C stack overflow) */
|
|
||||||
final LuaString s;
|
final LuaString s;
|
||||||
final LuaString p;
|
final LuaString p;
|
||||||
final Varargs args;
|
final Varargs args;
|
||||||
@@ -863,12 +852,10 @@ public class StringLib extends TwoArgFunction {
|
|||||||
this.level = 0;
|
this.level = 0;
|
||||||
this.cinit = new int[ MAX_CAPTURES ];
|
this.cinit = new int[ MAX_CAPTURES ];
|
||||||
this.clen = new int[ MAX_CAPTURES ];
|
this.clen = new int[ MAX_CAPTURES ];
|
||||||
this.matchdepth = MAXCCALLS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
level = 0;
|
level = 0;
|
||||||
this.matchdepth = MAXCCALLS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void add_s( Buffer lbuf, LuaString news, int soff, int e ) {
|
private void add_s( Buffer lbuf, LuaString news, int soff, int e ) {
|
||||||
@@ -879,14 +866,8 @@ public class StringLib extends TwoArgFunction {
|
|||||||
lbuf.append( (byte) b );
|
lbuf.append( (byte) b );
|
||||||
} else {
|
} else {
|
||||||
++i; // skip ESC
|
++i; // skip ESC
|
||||||
b = (byte)(i < l ? news.luaByte( i ) : 0);
|
b = (byte) news.luaByte( i );
|
||||||
if ( !Character.isDigit( (char) b ) ) {
|
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 );
|
lbuf.append( b );
|
||||||
} else if ( b == '0' ) {
|
} else if ( b == '0' ) {
|
||||||
lbuf.append( s.substring( soff, e ) );
|
lbuf.append( s.substring( soff, e ) );
|
||||||
@@ -943,7 +924,7 @@ public class StringLib extends TwoArgFunction {
|
|||||||
if ( i == 0 ) {
|
if ( i == 0 ) {
|
||||||
return s.substring( soff, end );
|
return s.substring( soff, end );
|
||||||
} else {
|
} else {
|
||||||
return error( "invalid capture index %" + (i + 1) );
|
return error( "invalid capture index" );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int l = clen[i];
|
int l = clen[i];
|
||||||
@@ -962,7 +943,7 @@ public class StringLib extends TwoArgFunction {
|
|||||||
private int check_capture( int l ) {
|
private int check_capture( int l ) {
|
||||||
l -= '1';
|
l -= '1';
|
||||||
if ( l < 0 || l >= level || this.clen[l] == CAP_UNFINISHED ) {
|
if ( l < 0 || l >= level || this.clen[l] == CAP_UNFINISHED ) {
|
||||||
error("invalid capture index %" + (l + 1));
|
error("invalid capture index");
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
@@ -980,19 +961,19 @@ public class StringLib extends TwoArgFunction {
|
|||||||
switch ( p.luaByte( poffset++ ) ) {
|
switch ( p.luaByte( poffset++ ) ) {
|
||||||
case L_ESC:
|
case L_ESC:
|
||||||
if ( poffset == p.length() ) {
|
if ( poffset == p.length() ) {
|
||||||
error( "malformed pattern (ends with '%')" );
|
error( "malformed pattern (ends with %)" );
|
||||||
}
|
}
|
||||||
return poffset + 1;
|
return poffset + 1;
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
if ( poffset != p.length() && p.luaByte( poffset ) == '^' ) poffset++;
|
if ( p.luaByte( poffset ) == '^' ) poffset++;
|
||||||
do {
|
do {
|
||||||
if ( poffset == p.length() ) {
|
if ( poffset == p.length() ) {
|
||||||
error( "malformed pattern (missing ']')" );
|
error( "malformed pattern (missing ])" );
|
||||||
}
|
}
|
||||||
if ( p.luaByte( poffset++ ) == L_ESC && poffset < p.length() )
|
if ( p.luaByte( poffset++ ) == L_ESC && poffset != p.length() )
|
||||||
poffset++; /* skip escapes (e.g. '%]') */
|
poffset++;
|
||||||
} while ( poffset == p.length() || p.luaByte( poffset ) != ']' );
|
} while ( p.luaByte( poffset ) != ']' );
|
||||||
return poffset + 1;
|
return poffset + 1;
|
||||||
default:
|
default:
|
||||||
return poffset;
|
return poffset;
|
||||||
@@ -1012,10 +993,9 @@ public class StringLib extends TwoArgFunction {
|
|||||||
case 'c': res = ( cdata & MASK_CONTROL ) != 0; break;
|
case 'c': res = ( cdata & MASK_CONTROL ) != 0; break;
|
||||||
case 'p': res = ( cdata & MASK_PUNCT ) != 0; break;
|
case 'p': res = ( cdata & MASK_PUNCT ) != 0; break;
|
||||||
case 's': res = ( cdata & MASK_SPACE ) != 0; break;
|
case 's': res = ( cdata & MASK_SPACE ) != 0; break;
|
||||||
case 'g': res = ( cdata & ( MASK_ALPHA | MASK_DIGIT | MASK_PUNCT ) ) != 0; break;
|
|
||||||
case 'w': res = ( cdata & ( MASK_ALPHA | MASK_DIGIT ) ) != 0; break;
|
case 'w': res = ( cdata & ( MASK_ALPHA | MASK_DIGIT ) ) != 0; break;
|
||||||
case 'x': res = ( cdata & MASK_HEXDIGIT ) != 0; break;
|
case 'x': res = ( cdata & MASK_HEXDIGIT ) != 0; break;
|
||||||
case 'z': res = ( c == 0 ); break; /* deprecated option */
|
case 'z': res = ( c == 0 ); break;
|
||||||
default: return cl == c;
|
default: return cl == c;
|
||||||
}
|
}
|
||||||
return ( lcl == cl ) ? res : !res;
|
return ( lcl == cl ) ? res : !res;
|
||||||
@@ -1057,8 +1037,6 @@ public class StringLib extends TwoArgFunction {
|
|||||||
* where match ends, otherwise returns -1.
|
* where match ends, otherwise returns -1.
|
||||||
*/
|
*/
|
||||||
int match( int soffset, int poffset ) {
|
int match( int soffset, int poffset ) {
|
||||||
if (matchdepth-- == 0) error("pattern too complex");
|
|
||||||
try {
|
|
||||||
while ( true ) {
|
while ( true ) {
|
||||||
// Check if we are at the end of the pattern -
|
// Check if we are at the end of the pattern -
|
||||||
// equivalent to the '\0' case in the C version, but our pattern
|
// equivalent to the '\0' case in the C version, but our pattern
|
||||||
@@ -1084,14 +1062,13 @@ public class StringLib extends TwoArgFunction {
|
|||||||
continue;
|
continue;
|
||||||
case 'f': {
|
case 'f': {
|
||||||
poffset += 2;
|
poffset += 2;
|
||||||
if ( poffset == p.length() || p.luaByte( poffset ) != '[' ) {
|
if ( p.luaByte( poffset ) != '[' ) {
|
||||||
error("missing '[' after '%f' in pattern");
|
error("Missing [ after %f in pattern");
|
||||||
}
|
}
|
||||||
int ep = classend( poffset );
|
int ep = classend( poffset );
|
||||||
int previous = ( soffset == 0 ) ? '\0' : s.luaByte( soffset - 1 );
|
int previous = ( soffset == 0 ) ? -1 : s.luaByte( soffset - 1 );
|
||||||
int next = ( soffset == s.length() ) ? '\0' : s.luaByte( soffset );
|
|
||||||
if ( matchbracketclass( previous, poffset, ep - 1 ) ||
|
if ( matchbracketclass( previous, poffset, ep - 1 ) ||
|
||||||
!matchbracketclass( next, poffset, ep - 1 ) )
|
matchbracketclass( s.luaByte( soffset ), poffset, ep - 1 ) )
|
||||||
return -1;
|
return -1;
|
||||||
poffset = ep;
|
poffset = ep;
|
||||||
continue;
|
continue;
|
||||||
@@ -1135,9 +1112,6 @@ public class StringLib extends TwoArgFunction {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
matchdepth++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int max_expand( int soff, int poff, int ep ) {
|
int max_expand( int soff, int poff, int ep ) {
|
||||||
@@ -1201,7 +1175,7 @@ public class StringLib extends TwoArgFunction {
|
|||||||
int matchbalance( int soff, int poff ) {
|
int matchbalance( int soff, int poff ) {
|
||||||
final int plen = p.length();
|
final int plen = p.length();
|
||||||
if ( poff == plen || poff + 1 == plen ) {
|
if ( poff == plen || poff + 1 == plen ) {
|
||||||
error( "malformed pattern (missing arguments to '%b')" );
|
error( "unbalanced pattern" );
|
||||||
}
|
}
|
||||||
final int slen = s.length();
|
final int slen = s.length();
|
||||||
if ( soff >= slen )
|
if ( soff >= slen )
|
||||||
|
|||||||
@@ -70,10 +70,16 @@ public class TableLib extends TwoArgFunction {
|
|||||||
table.set("sort", new sort());
|
table.set("sort", new sort());
|
||||||
table.set("unpack", new unpack());
|
table.set("unpack", new unpack());
|
||||||
env.set("table", table);
|
env.set("table", table);
|
||||||
if (!env.get("package").isnil()) env.get("package").get("loaded").set("table", table);
|
env.get("package").get("loaded").set("table", table);
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class TableLibFunction extends LibFunction {
|
||||||
|
public LuaValue call() {
|
||||||
|
return argerror(1, "table expected, got no value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// "concat" (table [, sep [, i [, j]]]) -> string
|
// "concat" (table [, sep [, i [, j]]]) -> string
|
||||||
static class concat extends TableLibFunction {
|
static class concat extends TableLibFunction {
|
||||||
public LuaValue call(LuaValue list) {
|
public LuaValue call(LuaValue list) {
|
||||||
@@ -94,21 +100,17 @@ public class TableLib extends TwoArgFunction {
|
|||||||
static class insert extends VarArgFunction {
|
static class insert extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
switch (args.narg()) {
|
switch (args.narg()) {
|
||||||
|
case 0: case 1: {
|
||||||
|
return argerror(2, "value expected");
|
||||||
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
LuaTable table = args.checktable(1);
|
LuaTable table = args.arg1().checktable();
|
||||||
table.insert(table.length()+1,args.arg(2));
|
table.insert(table.length()+1,args.arg(2));
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
case 3: {
|
|
||||||
LuaTable table = args.checktable(1);
|
|
||||||
int pos = args.checkint(2);
|
|
||||||
int max = table.length() + 1;
|
|
||||||
if (pos < 1 || pos > max) argerror(2, "position out of bounds: " + pos + " not between 1 and " + max);
|
|
||||||
table.insert(pos, args.arg(3));
|
|
||||||
return NONE;
|
|
||||||
}
|
|
||||||
default: {
|
default: {
|
||||||
return error("wrong number of arguments to 'table.insert': " + args.narg() + " (must be 2 or 3)");
|
args.arg1().checktable().insert(args.checkint(2),args.arg(3));
|
||||||
|
return NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,21 +128,15 @@ public class TableLib extends TwoArgFunction {
|
|||||||
// "remove" (table [, pos]) -> removed-ele
|
// "remove" (table [, pos]) -> removed-ele
|
||||||
static class remove extends VarArgFunction {
|
static class remove extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaTable table = args.checktable(1);
|
return args.arg1().checktable().remove(args.optint(2, 0));
|
||||||
int size = table.length();
|
|
||||||
int pos = args.optint(2, size);
|
|
||||||
if (pos != size && (pos < 1 || pos > size + 1)) {
|
|
||||||
argerror(2, "position out of bounds: " + pos + " not between 1 and " + (size + 1));
|
|
||||||
}
|
|
||||||
return table.remove(pos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// "sort" (table [, comp])
|
// "sort" (table [, comp])
|
||||||
static class sort extends VarArgFunction {
|
static class sort extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
args.checktable(1).sort(
|
args.arg1().checktable().sort(
|
||||||
args.isnil(2)? NIL: args.checkfunction(2));
|
args.arg(2).isnil()? NIL: args.arg(2).checkfunction());
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,9 +146,11 @@ public class TableLib extends TwoArgFunction {
|
|||||||
static class unpack extends VarArgFunction {
|
static class unpack extends VarArgFunction {
|
||||||
public Varargs invoke(Varargs args) {
|
public Varargs invoke(Varargs args) {
|
||||||
LuaTable t = args.checktable(1);
|
LuaTable t = args.checktable(1);
|
||||||
// do not waste resource for calc rawlen if arg3 is not nil
|
switch (args.narg()) {
|
||||||
int len = args.arg(3).isnil() ? t.length() : 0;
|
case 1: return t.unpack();
|
||||||
return t.unpack(args.optint(2, 1), args.optint(3, len));
|
case 2: return t.unpack(args.checkint(2));
|
||||||
|
default: return t.unpack(args.checkint(2), args.checkint(3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package org.luaj.vm2.lib;
|
|
||||||
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
|
|
||||||
class TableLibFunction extends LibFunction {
|
|
||||||
public LuaValue call() {
|
|
||||||
return argerror(1, "table expected, got no value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -101,7 +101,7 @@ abstract public class Visitor {
|
|||||||
visitExps(args.exps);
|
visitExps(args.exps);
|
||||||
}
|
}
|
||||||
public void visit(TableField field) {
|
public void visit(TableField field) {
|
||||||
if ( field.name != null )
|
if ( field.name != null );
|
||||||
visit( field.name );
|
visit( field.name );
|
||||||
if ( field.index != null )
|
if ( field.index != null )
|
||||||
field.index.accept(this);
|
field.index.accept(this);
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.vm2.lib.jse;
|
package org.luaj.vm2.lib.jse;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -134,7 +133,7 @@ public class CoerceJavaToLua {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static final Map COERCIONS = Collections.synchronizedMap(new HashMap());
|
static final Map COERCIONS = new HashMap();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Coercion boolCoercion = new BoolCoercion() ;
|
Coercion boolCoercion = new BoolCoercion() ;
|
||||||
|
|||||||
@@ -174,13 +174,13 @@ public class CoerceLuaToJava {
|
|||||||
|
|
||||||
public Object coerce(LuaValue value) {
|
public Object coerce(LuaValue value) {
|
||||||
switch ( targetType ) {
|
switch ( targetType ) {
|
||||||
case TARGET_TYPE_BYTE: return (byte) value.toint() ;
|
case TARGET_TYPE_BYTE: return new Byte( (byte) value.toint() );
|
||||||
case TARGET_TYPE_CHAR: return (char) value.toint() ;
|
case TARGET_TYPE_CHAR: return new Character( (char) value.toint() );
|
||||||
case TARGET_TYPE_SHORT: return (short) value.toint();
|
case TARGET_TYPE_SHORT: return new Short( (short) value.toint() );
|
||||||
case TARGET_TYPE_INT: return value.toint();
|
case TARGET_TYPE_INT: return new Integer( (int) value.toint() );
|
||||||
case TARGET_TYPE_LONG: return (long) value.todouble();
|
case TARGET_TYPE_LONG: return new Long( (long) value.todouble() );
|
||||||
case TARGET_TYPE_FLOAT: return (float) value.todouble();
|
case TARGET_TYPE_FLOAT: return new Float( (float) value.todouble() );
|
||||||
case TARGET_TYPE_DOUBLE: return (double) value.todouble();
|
case TARGET_TYPE_DOUBLE: return new Double( (double) value.todouble() );
|
||||||
default: return null;
|
default: return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -308,7 +308,7 @@ public class CoerceLuaToJava {
|
|||||||
public Object coerce(LuaValue value) {
|
public Object coerce(LuaValue value) {
|
||||||
switch ( value.type() ) {
|
switch ( value.type() ) {
|
||||||
case LuaValue.TNUMBER:
|
case LuaValue.TNUMBER:
|
||||||
return value.isint()? value.toint() : value.todouble();
|
return value.isint()? (Object)new Integer(value.toint()): (Object)new Double(value.todouble());
|
||||||
case LuaValue.TBOOLEAN:
|
case LuaValue.TBOOLEAN:
|
||||||
return value.toboolean()? Boolean.TRUE: Boolean.FALSE;
|
return value.toboolean()? Boolean.TRUE: Boolean.FALSE;
|
||||||
case LuaValue.TSTRING:
|
case LuaValue.TSTRING:
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.vm2.lib.jse;
|
package org.luaj.vm2.lib.jse;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -107,10 +106,9 @@ public class JseBaseLib extends org.luaj.vm2.lib.BaseLib {
|
|||||||
if ( ! f.exists() )
|
if ( ! f.exists() )
|
||||||
return super.findResource(filename);
|
return super.findResource(filename);
|
||||||
try {
|
try {
|
||||||
return new BufferedInputStream(new FileInputStream(f));
|
return new FileInputStream(f);
|
||||||
} catch ( IOException ioe ) {
|
} catch ( IOException ioe ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ public class JseIoLib extends IoLib {
|
|||||||
this( null, null, o );
|
this( null, null, o );
|
||||||
}
|
}
|
||||||
public String tojstring() {
|
public String tojstring() {
|
||||||
return "file (" + (this.closed ? "closed" : String.valueOf(this.hashCode())) + ")";
|
return "file ("+this.hashCode()+")";
|
||||||
}
|
}
|
||||||
public boolean isstdfile() {
|
public boolean isstdfile() {
|
||||||
return file == null;
|
return file == null;
|
||||||
@@ -321,7 +321,7 @@ public class JseIoLib extends IoLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int remaining() throws IOException {
|
public int remaining() throws IOException {
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int peek() throws IOException, EOFException {
|
public int peek() throws IOException, EOFException {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ package org.luaj.vm2.lib.jse;
|
|||||||
import org.luaj.vm2.Globals;
|
import org.luaj.vm2.Globals;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
import org.luaj.vm2.lib.LibFunction;
|
import org.luaj.vm2.lib.LibFunction;
|
||||||
import org.luaj.vm2.lib.TwoArgFunction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subclass of {@link LibFunction} which implements the lua standard {@code math}
|
* Subclass of {@link LibFunction} which implements the lua standard {@code math}
|
||||||
@@ -77,9 +76,8 @@ public class JseMathLib extends org.luaj.vm2.lib.MathLib {
|
|||||||
LuaValue math = env.get("math");
|
LuaValue math = env.get("math");
|
||||||
math.set("acos", new acos());
|
math.set("acos", new acos());
|
||||||
math.set("asin", new asin());
|
math.set("asin", new asin());
|
||||||
LuaValue atan = new atan2();
|
math.set("atan", new atan());
|
||||||
math.set("atan", atan);
|
math.set("atan2", new atan2());
|
||||||
math.set("atan2", atan);
|
|
||||||
math.set("cosh", new cosh());
|
math.set("cosh", new cosh());
|
||||||
math.set("exp", new exp());
|
math.set("exp", new exp());
|
||||||
math.set("log", new log());
|
math.set("log", new log());
|
||||||
@@ -91,21 +89,11 @@ public class JseMathLib extends org.luaj.vm2.lib.MathLib {
|
|||||||
|
|
||||||
static final class acos extends UnaryOp { protected double call(double d) { return Math.acos(d); } }
|
static final class acos extends UnaryOp { protected double call(double d) { return Math.acos(d); } }
|
||||||
static final class asin extends UnaryOp { protected double call(double d) { return Math.asin(d); } }
|
static final class asin extends UnaryOp { protected double call(double d) { return Math.asin(d); } }
|
||||||
static final class atan2 extends TwoArgFunction {
|
static final class atan extends UnaryOp { protected double call(double d) { return Math.atan(d); } }
|
||||||
public LuaValue call(LuaValue x, LuaValue y) {
|
static final class atan2 extends BinaryOp { protected double call(double y, double x) { return Math.atan2(y, x); } }
|
||||||
return valueOf(Math.atan2(x.checkdouble(), y.optdouble(1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static final class cosh extends UnaryOp { protected double call(double d) { return Math.cosh(d); } }
|
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 exp extends UnaryOp { protected double call(double d) { return Math.exp(d); } }
|
||||||
static final class log extends TwoArgFunction {
|
static final class log extends UnaryOp { protected double call(double d) { return Math.log(d); } }
|
||||||
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 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 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); } }
|
static final class tanh extends UnaryOp { protected double call(double d) { return Math.tanh(d); } }
|
||||||
@@ -117,4 +105,3 @@ public class JseMathLib extends org.luaj.vm2.lib.MathLib {
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,13 +74,13 @@ import org.luaj.vm2.lib.OsLib;
|
|||||||
public class JseOsLib extends org.luaj.vm2.lib.OsLib {
|
public class JseOsLib extends org.luaj.vm2.lib.OsLib {
|
||||||
|
|
||||||
/** return code indicating the execute() threw an I/O exception */
|
/** return code indicating the execute() threw an I/O exception */
|
||||||
public static final int EXEC_IOEXCEPTION = 1;
|
public static int EXEC_IOEXCEPTION = 1;
|
||||||
|
|
||||||
/** return code indicating the execute() was interrupted */
|
/** return code indicating the execute() was interrupted */
|
||||||
public static final int EXEC_INTERRUPTED = -2;
|
public static int EXEC_INTERRUPTED = -2;
|
||||||
|
|
||||||
/** return code indicating the execute() threw an unknown exception */
|
/** return code indicating the execute() threw an unknown exception */
|
||||||
public static final int EXEC_ERROR = -3;
|
public static int EXEC_ERROR = -3;
|
||||||
|
|
||||||
/** public constructor */
|
/** public constructor */
|
||||||
public JseOsLib() {
|
public JseOsLib() {
|
||||||
@@ -120,13 +120,13 @@ public class JseOsLib extends org.luaj.vm2.lib.OsLib {
|
|||||||
if ( ! f.exists() )
|
if ( ! f.exists() )
|
||||||
throw new IOException("No such file or directory");
|
throw new IOException("No such file or directory");
|
||||||
if ( ! f.renameTo(new File(newname)) )
|
if ( ! f.renameTo(new File(newname)) )
|
||||||
throw new IOException("Failed to rename");
|
throw new IOException("Failed to delete");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String tmpname() {
|
protected String tmpname() {
|
||||||
try {
|
try {
|
||||||
java.io.File f = java.io.File.createTempFile(TMP_PREFIX ,TMP_SUFFIX);
|
java.io.File f = java.io.File.createTempFile(TMP_PREFIX ,TMP_SUFFIX);
|
||||||
return f.getAbsolutePath();
|
return f.getName();
|
||||||
} catch ( IOException ioe ) {
|
} catch ( IOException ioe ) {
|
||||||
return super.tmpname();
|
return super.tmpname();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ package org.luaj.vm2.lib.jse;
|
|||||||
|
|
||||||
import org.luaj.vm2.Globals;
|
import org.luaj.vm2.Globals;
|
||||||
import org.luaj.vm2.LoadState;
|
import org.luaj.vm2.LoadState;
|
||||||
|
import org.luaj.vm2.LuaThread;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.luaj.vm2.LuaValue;
|
||||||
import org.luaj.vm2.Varargs;
|
|
||||||
import org.luaj.vm2.compiler.LuaC;
|
import org.luaj.vm2.compiler.LuaC;
|
||||||
import org.luaj.vm2.lib.Bit32Lib;
|
import org.luaj.vm2.lib.Bit32Lib;
|
||||||
import org.luaj.vm2.lib.CoroutineLib;
|
import org.luaj.vm2.lib.CoroutineLib;
|
||||||
@@ -97,7 +97,7 @@ public class JsePlatform {
|
|||||||
globals.load(new PackageLib());
|
globals.load(new PackageLib());
|
||||||
globals.load(new Bit32Lib());
|
globals.load(new Bit32Lib());
|
||||||
globals.load(new TableLib());
|
globals.load(new TableLib());
|
||||||
globals.load(new JseStringLib());
|
globals.load(new StringLib());
|
||||||
globals.load(new CoroutineLib());
|
globals.load(new CoroutineLib());
|
||||||
globals.load(new JseMathLib());
|
globals.load(new JseMathLib());
|
||||||
globals.load(new JseIoLib());
|
globals.load(new JseIoLib());
|
||||||
@@ -124,11 +124,10 @@ public class JsePlatform {
|
|||||||
|
|
||||||
|
|
||||||
/** Simple wrapper for invoking a lua function with command line arguments.
|
/** Simple wrapper for invoking a lua function with command line arguments.
|
||||||
* The supplied function is first given a new Globals object as its environment
|
* The supplied function is first given a new Globals object,
|
||||||
* then the program is run with arguments.
|
* then the program is run with arguments.
|
||||||
* @return {@link Varargs} containing any values returned by mainChunk.
|
|
||||||
*/
|
*/
|
||||||
public static Varargs luaMain(LuaValue mainChunk, String[] args) {
|
public static void luaMain(LuaValue mainChunk, String[] args) {
|
||||||
Globals g = standardGlobals();
|
Globals g = standardGlobals();
|
||||||
int n = args.length;
|
int n = args.length;
|
||||||
LuaValue[] vargs = new LuaValue[args.length];
|
LuaValue[] vargs = new LuaValue[args.length];
|
||||||
@@ -138,6 +137,6 @@ public class JsePlatform {
|
|||||||
arg.set("n", n);
|
arg.set("n", n);
|
||||||
g.set("arg", arg);
|
g.set("arg", arg);
|
||||||
mainChunk.initupvalue1(g);
|
mainChunk.initupvalue1(g);
|
||||||
return mainChunk.invoke(LuaValue.varargsOf(vargs));
|
mainChunk.invoke(LuaValue.varargsOf(vargs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2.lib.jse;
|
|
||||||
|
|
||||||
public class JseStringLib extends org.luaj.vm2.lib.StringLib {
|
|
||||||
|
|
||||||
/** public constructor */
|
|
||||||
public JseStringLib() {
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String format(String src, double x) {
|
|
||||||
String out;
|
|
||||||
try {
|
|
||||||
out = String.format(src, new Object[] {Double.valueOf(x)});
|
|
||||||
} catch (Throwable e) {
|
|
||||||
out = super.format(src, x);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -112,7 +112,7 @@ public class LuajavaLib extends VarArgFunction {
|
|||||||
LuaTable t = new LuaTable();
|
LuaTable t = new LuaTable();
|
||||||
bind( t, this.getClass(), NAMES, BINDCLASS );
|
bind( t, this.getClass(), NAMES, BINDCLASS );
|
||||||
env.set("luajava", t);
|
env.set("luajava", t);
|
||||||
if (!env.get("package").isnil()) env.get("package").get("loaded").set("luajava", t);
|
env.get("package").get("loaded").set("luajava", t);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
case BINDCLASS: {
|
case BINDCLASS: {
|
||||||
|
|||||||
@@ -244,8 +244,8 @@ public class LuaScriptEngine extends AbstractScriptEngine implements ScriptEngin
|
|||||||
case LuaValue.TSTRING: return luajValue.tojstring();
|
case LuaValue.TSTRING: return luajValue.tojstring();
|
||||||
case LuaValue.TUSERDATA: return luajValue.checkuserdata(Object.class);
|
case LuaValue.TUSERDATA: return luajValue.checkuserdata(Object.class);
|
||||||
case LuaValue.TNUMBER: return luajValue.isinttype()?
|
case LuaValue.TNUMBER: return luajValue.isinttype()?
|
||||||
luajValue.toint():
|
(Object) new Integer(luajValue.toint()):
|
||||||
luajValue.todouble();
|
(Object) new Double(luajValue.todouble());
|
||||||
default: return luajValue;
|
default: return luajValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import org.luaj.vm2.compiler.DumpLoadEndianIntTest;
|
|||||||
import org.luaj.vm2.compiler.LuaParserTests;
|
import org.luaj.vm2.compiler.LuaParserTests;
|
||||||
import org.luaj.vm2.compiler.RegressionTests;
|
import org.luaj.vm2.compiler.RegressionTests;
|
||||||
import org.luaj.vm2.compiler.SimpleTests;
|
import org.luaj.vm2.compiler.SimpleTests;
|
||||||
import org.luaj.vm2.lib.jse.JsePlatformTest;
|
|
||||||
import org.luaj.vm2.lib.jse.LuaJavaCoercionTest;
|
import org.luaj.vm2.lib.jse.LuaJavaCoercionTest;
|
||||||
import org.luaj.vm2.lib.jse.LuajavaAccessibleMembersTest;
|
import org.luaj.vm2.lib.jse.LuajavaAccessibleMembersTest;
|
||||||
import org.luaj.vm2.lib.jse.LuajavaClassMembersTest;
|
import org.luaj.vm2.lib.jse.LuajavaClassMembersTest;
|
||||||
@@ -86,7 +85,6 @@ public class AllTests {
|
|||||||
|
|
||||||
// library tests
|
// library tests
|
||||||
TestSuite lib = new TestSuite("Library Tests");
|
TestSuite lib = new TestSuite("Library Tests");
|
||||||
lib.addTestSuite(JsePlatformTest.class);
|
|
||||||
lib.addTestSuite(LuajavaAccessibleMembersTest.class);
|
lib.addTestSuite(LuajavaAccessibleMembersTest.class);
|
||||||
lib.addTestSuite(LuajavaClassMembersTest.class);
|
lib.addTestSuite(LuajavaClassMembersTest.class);
|
||||||
lib.addTestSuite(LuaJavaCoercionTest.class);
|
lib.addTestSuite(LuaJavaCoercionTest.class);
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package org.luaj.vm2.lib.jse;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.Varargs;
|
|
||||||
|
|
||||||
|
|
||||||
public class JsePlatformTest extends TestCase {
|
|
||||||
public void testLuaMainPassesArguments() {
|
|
||||||
Globals globals = JsePlatform.standardGlobals();
|
|
||||||
LuaValue chunk = globals.load("return #arg, arg.n, arg[2], arg[1]");
|
|
||||||
Varargs results = JsePlatform.luaMain(chunk, new String[] { "aaa", "bbb" });
|
|
||||||
assertEquals(results.narg(), 4);
|
|
||||||
assertEquals(results.arg(1), LuaValue.valueOf(2));
|
|
||||||
assertEquals(results.arg(2), LuaValue.valueOf(2));
|
|
||||||
assertEquals(results.arg(3), LuaValue.valueOf("bbb"));
|
|
||||||
assertEquals(results.arg(4), LuaValue.valueOf("aaa"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +1 @@
|
|||||||
version: 3.1.0
|
version: 3.0.1
|
||||||
Reference in New Issue
Block a user