46 Commits

Author SHA1 Message Date
UnlegitDqrk
48d880b218 Updated README 2026-03-03 12:17:06 +01:00
UnlegitDqrk
4f3066d1cc Added JavaDocs 2026-03-03 12:12:44 +01:00
UnlegitDqrk
e127fbf988 Added license notice 2026-03-03 12:00:16 +01:00
UnlegitDqrk
9721ea66b7 Version fix 2026-03-03 11:59:03 +01:00
UnlegitDqrk
c7b5cf8986 Added missing licenses 2026-03-03 11:54:14 +01:00
UnlegitDqrk
d917ba6146 Updated to Lua 5.5 2026-03-03 11:48:26 +01:00
UnlegitDqrk
862296b343 Updated to Lua 5.4 2026-03-03 10:55:46 +01:00
UnlegitDqrk
67429a7a31 Fixed issue: #55 2026-03-02 15:49:57 +01:00
UnlegitDqrk
139af3f28b Implemented issue: #19 2026-03-02 15:42:55 +01:00
UnlegitDqrk
33d745d667 Implemented issue: #47 2026-03-02 15:36:05 +01:00
UnlegitDqrk
06c74072be Fixed issue: #47 2026-03-02 15:31:22 +01:00
UnlegitDqrk
63edacbb5f Fixed issue: #51 2026-03-02 15:28:31 +01:00
UnlegitDqrk
7aea99d650 Implemented issue: #56 2026-03-02 14:58:31 +01:00
UnlegitDqrk
921606b93f Implemented issue: #65 2026-03-02 14:48:30 +01:00
UnlegitDqrk
5f11997446 Implemented issue: #67 2026-03-02 14:44:54 +01:00
UnlegitDqrk
c735ac67a0 Fixed issue: #68 2026-03-02 14:37:27 +01:00
UnlegitDqrk
7f7185aa08 Fixed issue: #70 2026-03-02 14:27:11 +01:00
UnlegitDqrk
39ff4f204d Fixed issue: #71 2026-03-02 14:22:54 +01:00
UnlegitDqrk
9cb10a390f Fixed issue: #74 2026-03-02 14:14:14 +01:00
UnlegitDqrk
c60991a33c Fixed issue: #75 2026-03-02 14:11:08 +01:00
UnlegitDqrk
c8fdc62495 Fixed issue: #81 2026-03-02 14:07:54 +01:00
UnlegitDqrk
ff4033cad4 Implemented issue: #82 2026-03-02 13:48:14 +01:00
UnlegitDqrk
572fd95692 Fixed issue: #86 2026-03-02 13:31:34 +01:00
UnlegitDqrk
db392c4763 Implemented issue: #87 2026-03-02 13:10:29 +01:00
UnlegitDqrk
98437da1fa Fixed issue: #96 2026-03-02 12:52:07 +01:00
UnlegitDqrk
85ed36de51 Fixed issue: #101 2026-03-02 11:58:39 +01:00
UnlegitDqrk
1d3459e0d3 Started with upgrading to Lua 5.3 2026-03-01 21:42:37 +01:00
UnlegitDqrk
493b055a26 Started with upgrading to Lua 5.3 2026-03-01 21:42:19 +01:00
UnlegitDqrk
01a8bd944e Fixed issue: #108 2026-03-01 19:57:26 +01:00
UnlegitDqrk
4c2add3832 Fixed issue: #94 2026-03-01 19:36:19 +01:00
UnlegitDqrk
364dbecb17 Fixed issue: Invalid escape sequences in string literals not raising errors (e.g. \q) 2026-03-01 19:11:18 +01:00
UnlegitDqrk
86e4d78761 Fixed issue: tonumber("-") returns 0 #6 2026-03-01 18:47:22 +01:00
UnlegitDqrk
7338475ae4 Fixed LuaJC not writing java package to bytecode correctly 2026-03-01 13:11:33 +01:00
UnlegitDqrk
01739d4e77 Pull request: MAXSTACK = 1024;LUAI_MAXVARS = 1024; #46 2026-03-01 13:08:19 +01:00
UnlegitDqrk
37b68d4d85 Pull request: Reduce allocations per LuaClosure call #76 2026-03-01 13:06:19 +01:00
UnlegitDqrk
f30c4c3bec Fixed varargs invocation from luajava 2026-03-01 13:04:22 +01:00
UnlegitDqrk
d0c84972dd fixed bug: invoke java variable parameter type method problem 2026-03-01 13:01:18 +01:00
UnlegitDqrk
068451886d fixed bug: invoke overload method disorder 2026-03-01 12:59:23 +01:00
UnlegitDqrk
ba3d1d8ef9 Added missed Classes 2026-03-01 12:57:18 +01:00
UnlegitDqrk
405fd633fd Added missed Classes 2026-03-01 12:56:55 +01:00
UnlegitDqrk
f087e87806 Updated to Java 25 2026-03-01 12:50:46 +01:00
UnlegitDqrk
95ea3d84b6 Added licenses 2026-03-01 12:40:00 +01:00
UnlegitDqrk
f40e89e19c Implemented Support of Java 21 VirtualThread 2026-03-01 12:39:42 +01:00
40831d0f2d Update README.md 2026-03-01 10:33:16 +00:00
bba6df42fd Update README.md 2026-03-01 10:29:43 +00:00
3df6dc9e96 Update README.md 2026-03-01 10:29:28 +00:00
640 changed files with 12668 additions and 11265 deletions

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/core"/>
<classpathentry excluding="org/luaj/vm2/luajc/antlr/|org/luaj/vm2/luajc/lst/|org/luaj/vm2/luajc/JavaCodeGenerator.java" kind="src" path="src/jse"/>
<classpathentry kind="src" path="src/jme"/>
<classpathentry kind="src" path="test/java"/>
<classpathentry kind="src" path="test/junit"/>
<classpathentry kind="src" path="test/lua"/>
<classpathentry kind="src" path="examples/jse"/>
<classpathentry kind="src" path="examples/jme"/>
<classpathentry kind="src" path="examples/lua"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
<classpathentry kind="lib" path="lib/midpapi20.jar"/>
<classpathentry kind="lib" path="lib/cldcapi11.jar"/>
<classpathentry kind="lib" path="lib/bcel-5.2.jar"/>
<classpathentry kind="var" path="JRE_LIB"/>
<classpathentry kind="output" path="bin"/>
</classpath>

6
.gitignore vendored
View File

@@ -3,6 +3,12 @@ target/
build/ build/
lib/ lib/
jit/ jit/
core/target
core/build
jme/target
jme/build
jse/target
jse/build
*.ser *.ser
*.gz *.gz
*.jar *.jar

10
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

21
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="core" />
<module name="jme" />
<module name="jse" />
<module name="maven-example" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="jme" options="" />
</option>
</component>
</project>

7
.idea/discord.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT_FILES" />
<option name="description" value="" />
</component>
</project>

13
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/core/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/core/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/jme/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/jme/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/jse/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/jse/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

25
.idea/jarRepositories.xml generated Normal file
View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="oac" />
<option name="name" value="oac" />
<option name="url" value="https://repo.open-autonomous-connection.org/api/packages/open-autonomous-connection/maven" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

9
.idea/luaj.iml generated Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

18
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/examples/maven/pom.xml" />
<option value="$PROJECT_DIR$/core/pom.xml" />
<option value="$PROJECT_DIR$/jme/pom.xml" />
<option value="$PROJECT_DIR$/jse/pom.xml" />
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="25" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

3
.mvn/wrapper/maven-wrapper.properties vendored Normal file
View File

@@ -0,0 +1,3 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>luaj-vm</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

1089
README.md

File diff suppressed because it is too large Load Diff

View File

@@ -1,108 +0,0 @@
<!-- And build script to compile lua scripts into runnable jar files using the "luajc"
lua to java bytecode compiler.
Each source file is converted into a runnable jar file that takes arguments from the command line.
For example, the program test/lua/perf/binarytrees.lua is converted to a jar that can be run with
java -jar binarytrees.jar 15
-->
<project default="all">
<import file="build.xml"/>
<import file="build-libs.xml"/>
<available file="luaj-jse-${version}.jar" property="luaj.lib.exists"/>
<!-- this may need to be changed when building on mac -->
<property name="rt.jar" value="${java.home}/lib/rt.jar"/>
<target name="luaj-lib" unless="luaj.lib.exists">
<antcall target="jar-jse"/>
</target>
<macrodef name="perftest">
<attribute name="cmd"/>
<sequential>
<echo level="info">------ @{cmd}</echo>
<exec executable="bash">
<arg value="-c"/>
<arg value="time @{cmd}"/>
</exec>
</sequential>
</macrodef>
<macrodef name="buildappjar">
<attribute name="luaprog"/>
<attribute name="arg" default=""/>
<attribute name="srcdir" default="test/lua/perf"/>
<sequential>
<echo level="info">=========== @{srcdir}/@{luaprog} =============</echo>
<delete dir="build/@{luaprog}"/>
<mkdir dir="build/@{luaprog}/class"/>
<java classname="luajc">
<classpath>
<pathelement path="luaj-jse-${version}.jar"/>
<pathelement path="lib/bcel-5.2.jar"/>
</classpath>
<arg value="-s"/>
<arg path="@{srcdir}"/>
<arg value="-d"/>
<arg path="build/@{luaprog}/class"/>
<arg value="-m"/>
<arg value="-v"/>
<arg value="@{luaprog}.lua"/>
</java>
<jar destfile="build/@{luaprog}.jar">
<fileset dir="build/@{luaprog}/class"/>
<zipfileset includes="org/luaj/vm2/*.class,org/luaj/vm2/lib/*.class,org/luaj/vm2/lib/jse/*.class,org/luaj/vm2/compiler/*.class" src="luaj-jse-${version}.jar" />
<manifest>
<attribute name="Main-Class" value="@{luaprog}" />
</manifest>
</jar>
<unjar src="build/@{luaprog}.jar" dest="build/@{luaprog}/unjarred"/>
<perftest cmd="java -jar build/@{luaprog}.jar @{arg}"/>
<!-- The following can be adapted to produce an optimized jar.
<taskdef resource="proguard/ant/task.properties" classpath="lib/proguard.jar" />
<proguard>
-injars build/@{luaprog}.jar
-outjars build/@{luaprog}-opt.jar
-libraryjars ${rt.jar}
-overloadaggressively
-repackageclasses ''
-allowaccessmodification
-printmapping build/@{luaprog}.map
-keep public class @{luaprog} {
public static void main(java.lang.String[]);
}
</proguard>
<unjar src="build/@{luaprog}-opt.jar" dest="build/@{luaprog}/unjarred-opt"/>
<perftest cmd="java -jar build/@{luaprog}-opt.jar @{arg}"/>
-->
</sequential>
</macrodef>
<target name="binarytrees" depends="luaj-lib,proguard-lib">
<buildappjar luaprog="binarytrees" arg="15"/>
</target>
<target name="fannkuch" depends="luaj-lib,proguard-lib">
<buildappjar luaprog="fannkuch" arg="10"/>
</target>
<target name="nbody" depends="luaj-lib,proguard-lib">
<buildappjar luaprog="nbody" arg="1000000"/>
</target>
<target name="nsieve" depends="luaj-lib,proguard-lib">
<buildappjar luaprog="nsieve" arg="8"/>
</target>
<target name="swingapp" depends="luaj-lib,proguard-lib">
<buildappjar luaprog="swingapp" srcdir="examples/lua"/>
</target>
<target name="allappjars" depends="binarytrees,fannkuch,nbody,nsieve,swingapp"/>
<target name="all" depends="allappjars"/>
</project>

View File

@@ -1,116 +0,0 @@
<?xml version="1.0"?>
<project name="sample" default="main" basedir=".">
<property file="version.properties"/>
<!-- find libs -->
<import file="build-libs.xml"/>
<!-- main java class -->
<property name="java.dir" value="examples/jse"/>
<property name="java.name" value="SampleApplet"/>
<!-- main script -->
<property name="script.dir" value="examples/lua"/>
<property name="script.name" value="swingapplet"/>
<property name="image.name" value="logo.gif"/>
<!-- location of luaj jar -->
<property name="libs.dir" value="lib"/>
<property name="luaj.jar" value="${libs.dir}/luaj-jse-${version}.jar"/>
<!-- location of build results -->
<property name="build.dir" value="build/applet"/>
<target name="clean">
<delete failonerror="false" dir="${build.dir}"/>
</target>
<target name="dirs">
<mkdir dir="build/applet/classes"/>
</target>
<target name="classes" depends="dirs">
<copy todir="${build.dir}">
<fileset dir="${script.dir}" includes="${script.name}.lua,${image.name}"/>
</copy>
<javac destdir="${build.dir}/classes" source="1.4" target="1.4"
classpath="${luaj.jar}" srcdir="${java.dir}" includes="${java.name}.java"/>
</target>
<target name="manifest" depends="dirs">
<manifest file="${build.dir}/MANIFEST.MF">
<attribute name="Permissions" value="sandbox"/>
<attribute name="Main-class" value="${java.name}"/>
</manifest>
</target>
<target name="jar" depends="classes,manifest">
<jar destfile="${build.dir}/${script.name}.jar"
manifest="${build.dir}/MANIFEST.MF">
<fileset dir="${build.dir}" includes="*.lua"/>
<fileset dir="${build.dir}/classes"/>
<zipfileset
src="${luaj.jar}"
excludes="**/script/*,**/luajc/**,**/parser/**,**/ast/**,lua*"/>
</jar>
</target>
<target name="obf" depends="jar,proguard-lib">
<taskdef resource="proguard/ant/task.properties" classpath="lib/proguard.jar" />
<copy file="${build.dir}/${script.name}.jar"
tofile="${build.dir}/${script.name}-unobfuscated.jar"/>
<proguard>
-injars ${build.dir}/${script.name}-unobfuscated.jar
-outjars ${build.dir}/${script.name}.jar
-libraryjars ${java.home}/lib/rt.jar
-overloadaggressively
-repackageclasses ''
-allowaccessmodification
-printmapping ${build.dir}/mapping.txt
-keep public class * extends java.applet.Applet
-target 1.4
</proguard>
</target>
<target name="sign" depends="obf">
<signjar jar="${build.dir}/${script.name}.jar"
alias="${sign.alias}"
storepass="${sign.storepass}"
keypass="${sign.keypass}"
keystore="${sign.keystore}" />
</target>
<target name="html" depends="dirs">
<echoxml file="build/applet/LuajSampleApplet.html">
<html>
<head><title>Luaj Sample Applet</title></head>
<body>
<h1>Luaj Sample Applet</h1>
Requires browser that supports applets.
${script.name}
<applet archive='${script.name}.jar'
code='${java.name}.class'
width='800'
height='640' >
<param name='luaj.script' value='${script.name}.lua'/>
<param name="java_version" value="1.4+"/>
</applet>
</body>
</html>
</echoxml>
</target>
<target name="run" depends="jar,html">
<exec executable="open" spawn="true">
<arg value="-a Firefox"/>
<arg path="build/applet/LuajSampleApplet.html"/>
</exec>
</target>
<target name="all" depends="clean,sign,html,run"/>
<target name="main" depends="sign,html"/>
</project>

View File

@@ -1,119 +0,0 @@
<project default="all" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
<!--
Run code coverage for unit tests on the luaj vm and libraries.
-->
<property name="classes.dir" value="build/classes-debug" />
<property name="instrumented.dir" value="build/instrumented" />
<property name="reports.xml.dir" value="build/reports-junit-xml" />
<property name="reports.html.dir" value="build/reports-junit-html" />
<property name="coverage.xml.dir" value="build/reports-coverage-xml" />
<property name="coverage.html.dir" value="build/reports-coverage-html" />
<property name="cobertura.serfile" value="cobertura.ser" />
<property name="cobertura.logfile" value="cobertura.log" />
<artifact:dependencies filesetId="cobutura.fileset">
<dependency groupId="net.sourceforge.cobertura" artifactId="cobertura" version="1.9.4.1"/>
<dependency groupId="junit" artifactId="junit" version="3.8.1"/>
</artifact:dependencies>
<path id="cobertura.classpath">
<fileset refid="cobutura.fileset" />
</path>
<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
<import file="wtk.xml"/>
<property environment="env"/>
<target name="clean" description="Remove all files created by the build/test process.">
<delete dir="${classes.dir}" failonerror="yes"/>
<delete dir="${instrumented.dir}" failonerror="yes"/>
<delete file="${cobertura.logfile}" />
<delete file="${cobertura.serfile}" />
</target>
<target name="init">
<ant antfile="build.xml" target="bcel-lib"/>
<ant antfile="build.xml" target="luaj1-lib"/>
<mkdir dir="${classes.dir}" />
<mkdir dir="${instrumented.dir}" />
<mkdir dir="${reports.xml.dir}" />
<mkdir dir="${reports.html.dir}" />
<mkdir dir="${coverage.xml.dir}" />
<mkdir dir="${coverage.html.dir}" />
</target>
<target name="compile" depends="init,wtk-or-fail">
<javac destdir="${classes.dir}" debug="yes" target="1.5">
<classpath refid="cobertura.classpath" />
<classpath refid="wtk-libs" />
<classpath path="lib/bcel-5.2.jar" />
<src path="src/core"/>
<src path="src/jme"/>
<src path="src/jse"/>
<src path="test/junit"/>
</javac>
</target>
<target name="instrument" depends="compile">
<delete file="${cobertura.serfile}"/>
<delete dir="${instrumented.dir}" failonerror="no"/>
<cobertura-instrument datafile="${cobertura.serfile}" todir="${instrumented.dir}">
<fileset dir="${classes.dir}">
<include name="org/luaj/vm2/*.class" />
<include name="org/luaj/vm2/lib/*.class" />
<include name="org/luaj/vm2/lib/jse/*.class" />
<include name="org/luaj/vm2/lib/jme/*.class" />
<include name="org/luaj/vm2/compiler/*.class" />
<include name="org/luaj/vm2/luajc/*.class" />
<include name="org/luaj/vm2/lua2java/*.class" />
<include name="org/luaj/vm2/parser/*.class" />
<include name="org/luaj/vm2/ast/*.class" />
<exclude name="**/*Test*.class" />
</fileset>
</cobertura-instrument>
</target>
<target name="test">
<junit fork="yes" dir="${basedir}" showoutput="yes">
<sysproperty key="net.sourceforge.cobertura.serfile"
file="${basedir}/${cobertura.serfile}" />
<classpath location="${instrumented.dir}" />
<classpath location="${classes.dir}" />
<classpath refid="cobertura.classpath" />
<classpath location="test/lua" />
<classpath location="test/junit/org/luaj/vm2/compiler" />
<classpath location="test/junit/org/luaj/vm2/vm1" />
<classpath path="lib/bcel-5.2.jar" />
<formatter type="xml" />
<batchtest todir="${reports.xml.dir}">
<fileset dir="test/junit">
<include name="org/luaj/vm2/AllTests.java" />
</fileset>
</batchtest>
</junit>
<junitreport todir="${reports.xml.dir}">
<fileset dir="${reports.xml.dir}">
<include name="TEST-*.xml" />
</fileset>
<report format="frames" todir="${reports.html.dir}" />
</junitreport>
</target>
<target name="report">
<cobertura-report datafile="${cobertura.serfile}" destdir="${coverage.xml.dir}" format="xml" />
<cobertura-report datafile="${cobertura.serfile}" destdir="${coverage.html.dir}">
<fileset dir="src/core"/>
<fileset dir="src/jse"/>
<fileset dir="src/jme"/>
</cobertura-report>
</target>
<target name="coverage" depends="clean,init,compile,instrument,test,report"/>
<target name="all" depends="coverage" />
</project>

View File

@@ -1,56 +0,0 @@
<project default="all-libs">
<available file="lib/midpapi20.jar" property="midpapi.lib.exists"/>
<available file="lib/bcel-5.2.jar" property="bcel.lib.exists"/>
<available file="lib/javacc.jar" property="javacc.lib.exists"/>
<available file="lib/proguard.jar" property="proguard.lib.exists"/>
<available file="lib/antenna-bin-1.2.0-beta.jar" property="antenna.lib.exists"/>
<available file="lib/junit.jar" property="junit.lib.exists"/>
<available file="lib/cobertura.jar" property="cobertura.lib.exists"/>
<available file="lib/microemulator.jar" property="microemulator.lib.exists"/>
<macrodef name="download">
<attribute name="zipname"/>
<attribute name="jars" default="**/*.jar"/>
<sequential>
<mkdir dir="lib"/>
<get src="http://luaj.sourceforge.net/lib/@{zipname}.tar.gz"
dest="lib/@{zipname}.tar.gz"/>
<gunzip src="lib/@{zipname}.tar.gz" dest="lib/@{zipname}.tar"/>
<untar src="lib/@{zipname}.tar" dest="lib" overwrite="true">
<patternset>
<include name="@{jars}"/>
</patternset>
<mapper type="flatten"/>
</untar>
</sequential>
</macrodef>
<target name="wtk-libs" unless="midpapi.lib.exists">
<download zipname="wtk-2.5.2-api"/>
</target>
<target name="bcel-lib" unless="bcel.lib.exists">
<download zipname="/bcel-5.2"/>
</target>
<target name="javacc-lib" unless="javacc.lib.exists">
<download zipname="javacc-5.0"/>
</target>
<target name="proguard-lib" unless="proguard.lib.exists">
<download zipname="proguard4.6"/>
</target>
<target name="antenna-lib" unless="antenna.lib.exists">
<download zipname="antenna-bin-1.2.0-beta"/>
</target>
<target name="junit-lib" unless="junit.lib.exists">
<download zipname="junit-3.8.2"/>
</target>
<target name="cobertura-lib" unless="cobertura.lib.exists">
<download zipname="cobertura-1.9.4.1-bin"/>
</target>
<target name="microemulator-lib" unless="microemulator.lib.exists">
<download zipname="microemulator-2.0.4" jars="**/microemulator.jar"/>
</target>
<target name="all-libs" depends="wtk-libs,bcel-lib,javacc-lib,proguard-lib,antenna-lib,junit-lib,cobertura-lib"/>
</project>

View File

@@ -1,176 +0,0 @@
<project default="usage">
<!-- Ant file to deploy to maven once the distribution is released on sourceforge.
-->
<property file="version.properties"/>
<macrodef name="write_pom">
<attribute name="platform"/>
<attribute name="snapshot" default=""/>
<sequential>
<mkdir dir="build/maven-${version}"/>
<echo file="build/maven-${version}/luaj-@{platform}-${version}@{snapshot}.pom"><![CDATA[<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.luaj</groupId>
<artifactId>luaj-]]>@{platform}<![CDATA[</artifactId>
<version>]]>${version}@{snapshot}<![CDATA[</version>
<packaging>jar</packaging>
<name>luaj-]]>@{platform}<![CDATA[</name>
<description>Luaj ]]>${version}<![CDATA[ for the ]]>@{platform}<![CDATA[ platform</description>
<url>http://sourceforge.net/projects/luaj/</url>
<licenses>
<license>
<name>MIT License</name>
<url>http://luaj.sourceforge.net/license.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>jrosebor</id>
<name>James Roseborough</name>
<email>jim.roseborough@luaj.org</email>
<timezone>-8</timezone>
<roles></roles>
</developer>
<developer>
<id>ifarmer</id>
<name>Ian Farmer</name>
<email>ian.farmer@luaj.org</email>
<timezone>-8</timezone>
<roles></roles>
</developer>
</developers>
<scm>
<url>http://luaj.cvs.sourceforge.net/viewvc/luaj/luaj-vm/</url>
</scm>
</project>
]]></echo>
</sequential>
</macrodef>
<macrodef name="prepare_files">
<attribute name="platform"/>
<attribute name="snapshot" default=""/>
<sequential>
<mkdir dir="build/maven-${version}"/>
<write_pom platform="@{platform}" snapshot="@{snapshot}"/>
<copy file="luaj-${version}.zip" todir="build/maven-${version}"/>
<unzip src="build/maven-${version}/luaj-${version}.zip" dest="build/maven-${version}"/>
<copy file="build/maven-${version}/luaj-${version}/lib/luaj-@{platform}-${version}.jar" todir="build/maven-${version}"/>
<!-- make a -sources file -->
<mkdir dir="build/maven-${version}/sources-@{platform}"/>
<copy todir="build/maven-${version}/sources-@{platform}">
<fileset dir="build/maven-${version}/luaj-${version}/src/core"/>
<fileset dir="build/maven-${version}/luaj-${version}/src/@{platform}"/>
<filterchain>
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-@{platform} ${version}"'/></tokenfilter>
</filterchain>
</copy>
<zip destfile="build/maven-${version}/luaj-@{platform}-${version}-sources.jar"
basedir="build/maven-${version}/sources-@{platform}"/>
<!-- make a -javadoc file -->
<mkdir dir="build/maven-${version}/javadoc-@{platform}"/>
<javadoc defaultexcludes="yes"
destdir="build/maven-${version}/javadoc-@{platform}"
author="true"
version="true"
use="true"
windowtitle="Luaj API">
<fileset dir="build/maven-${version}/sources-@{platform}">
<include name="org/luaj/vm/*.java"/>
<include name="org/luaj/vm2/*.java"/>
<include name="org/luaj/vm2/server/*.java"/>
<include name="**/LuaC.java"/>
<include name="**/LuaJC.java"/>
<include name="**/lib/*/*.java"/>
</fileset>
<doctitle><![CDATA[<h1>Luaj API</h1>]]></doctitle>
<bottom><![CDATA[<i>Copyright &#169; 2007-2015 Luaj.org. All Rights Reserved.</i>]]></bottom>
<tag name="todo" scope="all" description="To do:"/>
<link offline="true" href="http://sourceforge.net/projects/luaj/" packagelistLoc="C:\tmp"/>
<link href="http://sourceforge.net/projects/luaj/"/>
</javadoc>
<zip destfile="build/maven-${version}/luaj-@{platform}-${version}-javadoc.jar"
basedir="build/maven-${version}/javadoc-@{platform}"/>
</sequential>
</macrodef>
<macrodef name="shapshot_files">
<attribute name="platform"/>
<sequential>
<exec executable="mvn">
<arg value="deploy:deploy-file"/>
<arg value="-Durl=https://oss.sonatype.org/content/repositories/snapshots"/>
<arg value="-DrepositoryId=nexus-releases"/>
<arg value="-DpomFile=build/maven-${version}/luaj-@{platform}-${version}-SNAPSHOT.pom"/>
<arg value="-Dfile=build/maven-${version}/luaj-@{platform}-${version}.jar"/>
<arg value="-Dsources=build/maven-${version}/luaj-@{platform}-${version}-sources.jar"/>
<arg value="-Djavadoc=build/maven-${version}/luaj-@{platform}-${version}-javadoc.jar"/>
</exec>
</sequential>
</macrodef>
<macrodef name="sign_and_deploy">
<attribute name="platform"/>
<sequential>
<exec executable="mvn">
<arg value="gpg:sign-and-deploy-file"/>
<arg value="-Durl=http://oss.sonatype.org/service/local/staging/deploy/maven2"/>
<arg value="-DrepositoryId=nexus-releases"/>
<arg value="-DpomFile=build/maven-${version}/luaj-@{platform}-${version}.pom"/>
<arg value="-Dfile=build/maven-${version}/luaj-@{platform}-${version}.jar"/>
<arg value="-Dsources=build/maven-${version}/luaj-@{platform}-${version}-sources.jar"/>
<arg value="-Djavadoc=build/maven-${version}/luaj-@{platform}-${version}-javadoc.jar"/>
</exec>
</sequential>
</macrodef>
<macrodef name="prepare_and_install">
<attribute name="platform"/>
<sequential>
<prepare_files platform="@{platform}"/>
<exec executable="mvn">
<arg value="install:install-file"/>
<arg value="-Dfile=build/maven-${version}/luaj-@{platform}-${version}.jar"/>
<arg value="-DpomFile=build/maven-${version}/luaj-@{platform}-${version}.pom"/>
</exec>
</sequential>
</macrodef>
<macrodef name="prepare_and_snapshot">
<attribute name="platform"/>
<sequential>
<prepare_files platform="@{platform}" snapshot="-SNAPSHOT"/>
<shapshot_files platform="@{platform}"/>
</sequential>
</macrodef>
<macrodef name="prepare_and_deploy">
<attribute name="platform"/>
<sequential>
<prepare_files platform="@{platform}"/>
<sign_and_deploy platform="@{platform}"/>
</sequential>
</macrodef>
<target name="install">
<prepare_and_install platform="jse"/>
<prepare_and_install platform="jme"/>
</target>
<target name="snapshot">
<prepare_and_snapshot platform="jse"/>
<prepare_and_snapshot platform="jme"/>
</target>
<target name="deploy">
<prepare_and_deploy platform="jse"/>
<prepare_and_deploy platform="jme"/>
</target>
<target name="usage">
<echo level="info">Usage: ant [-Dversion=${version}] -f build-maven.xml [install | shapshot | deploy]</echo>
</target>
</project>

View File

@@ -1,113 +0,0 @@
<?xml version="1.0"?>
<project name="sample" default="all" basedir=".">
<property file="version.properties"/>
<!-- find libs -->
<import file="build-libs.xml"/>
<!-- main script -->
<property name="script.name" value="hello"/>
<property name="script.dir" value="examples/lua"/>
<target name="clean">
<delete failonerror="false" dir="build"/>
</target>
<target name="dirs">
<mkdir dir="build"/>
<mkdir dir="build/tool"/>
<mkdir dir="build/classes"/>
</target>
<target name="tools" depends="dirs,bcel-lib,wtk-libs,microemulator-lib">
<javac destdir="build/tool" classpath="lib/bcel-5.2.jar">
<src path="src/core"/>
<src path="src/jse"/>
</javac>
</target>
<!-- compile script into lua bytecode -->
<target name="luac" depends="tools">
<java classname="luac" classpath="build/tool">
<arg line="-o build/classes/${script.name}.lua"/>
<arg line="${script.dir}/${script.name}.lua"/>
</java>
</target>
<!-- compile script into java bytecode -->
<target name="luajc" depends="tools,wtk-libs">
<java classname="luajc" classpath="build/tool:lib/bcel-5.2.jar">
<arg line="-verbose"/>
<arg line="-srcdir ${script.dir}"/>
<arg line="-destdir build/classes"/>
<arg line="${script.name}.lua"/>
</java>
</target>
<target name="classes" depends="dirs,wtk-libs">
<mkdir dir="build/midlet/src"/>
<copy todir="build/midlet/src">
<fileset dir="src/core"/>
<fileset dir="src/jme"/>
<fileset dir="examples/jme"/>
<filterchain>
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jme ${version}"'/></tokenfilter>
</filterchain>
</copy>
<path id="wtk-libs">
<pathelement path="lib/cldcapi11.jar"/>
<pathelement path="lib/midpapi20.jar"/>
<pathelement path="lib/mmapi.jar"/>
</path>
<javac destdir="build/classes" encoding="utf-8" source="1.3" target="1.2" bootclasspathref="wtk-libs"
srcdir="build/midlet/src"/>
</target>
<target name="jar" depends="luajc,classes">
<jar destfile="build/sample-plain.jar"
basedir="build/classes"/>
</target>
<target name="obf" depends="jar,proguard-lib">
<taskdef resource="proguard/ant/task.properties" classpath="lib/proguard.jar" />
<proguard>
-injars build/sample-plain.jar
-outjars build/sample.jar
-libraryjars lib/midpapi20.jar
-libraryjars lib/cldcapi11.jar
-overloadaggressively
-repackageclasses ''
-microedition
-keep public class SampleMIDlet
-keep public class * extends org.luaj.vm2.LuaValue
</proguard>
</target>
<target name="jad" depends="obf">
<length file="build/sample.jar" property="sample.jar.length" />
<echo level="info">Jar file length is ${sample.jar.length}</echo>
<manifest file="build/sample.jad">
<attribute name="Built-By" value="luaj-${version}"/>
<attribute name="MIDlet-Name" value="Luaj ${script.name}"/>
<attribute name="MIDlet-Version" value="${version}"/>
<attribute name="MIDlet-Vendor" value="luaj.org"/>
<attribute name="MIDlet-Description" value="Luaj Sample Midlet"/>
<attribute name="MIDlet-1" value="${script.name}-${version}, , SampleMIDlet"/>
<attribute name="MIDlet-Jar-URL" value="sample.jar"/>
<attribute name="MIDlet-Jar-Size" value="${sample.jar.length}"/>
<attribute name="script" value="${script.name}"/>
</manifest>
</target>
<target name="package" depends="jad,jar,obf"/>
<target name="run" depends="jad,jar,obf,microemulator-lib">
<java jar="lib/microemulator.jar" fork="true">
<arg path="build/sample.jad"/>
</java>
</target>
<target name="all" depends="clean,package,run"/>
</project>

View File

@@ -1,68 +0,0 @@
<project default="all">
<import file="build.xml"/>
<property name="lua.command" value="lua"/>
<available file="luaj-jse-${version}.jar" property="luaj.lib.exists"/>
<available file="lib/jill-1.0.1.jar" property="jill.lib.exists"/>
<available file="lib/kahlua.jar" property="kahlua.lib.exists"/>
<available file="lib/mochalua-1.0.jar" property="mochalua.lib.exists"/>
<target name="luaj-lib" unless="luaj.lib.exists">
<antcall target="jar-jse"/>
</target>
<target name="jill-lib" unless="jill.lib.exists">
<mkdir dir="lib"/>
<get src="http://jillcode.googlecode.com/files/jill-1.0.1.zip"
dest="lib/jill-1.0.1.zip"/>
<unzip src="lib/jill-1.0.1.zip" dest="lib" overwrite="true"/>
<ant dir="lib/jill-1.0.1" target="compile"/>
<jar destfile="lib/jill-1.0.1.jar" basedir="lib/jill-1.0.1/compiled"/>
</target>
<target name="kahlua-lib" unless="kahlua.lib.exists">
<get src="http://kahlua.googlecode.com/files/kahlua.jar"
dest="lib/kahlua.jar"/>
</target>
<target name="mochalua-lib" unless="mochalua.lib.exists">
<get src="http://mochalua.googlecode.com/files/Mochalua%201.0.jar"
dest="lib/mochalua-1.0.jar"/>
</target>
<target name="perf-libs" depends="luaj-lib,bcel-lib,jill-lib,kahlua-lib,mochalua-lib"/>
<macrodef name="perftest">
<attribute name="program" default="lua"/>
<attribute name="luaprog" default="fannkuch.lua 10"/>
<attribute name="basedir" default="test/lua/perf/"/>
<sequential>
<echo level="info">------ @{program} @{luaprog}</echo>
<exec executable="bash">
<arg value="-c"/>
<arg value="time @{program} @{basedir}@{luaprog}"/>
</exec>
</sequential>
</macrodef>
<macrodef name="testcase">
<attribute name="luaprog" default="fannkuch.lua 10"/>
<sequential>
<echo level="info">=========== @{luaprog} =============</echo>
<perftest program="java -version" luaprog="" basedir=""/>
<perftest program="${lua.command}" luaprog="@{luaprog}"/>
<perftest program="java -cp luaj-jse-${version}.jar lua -n" luaprog="@{luaprog}"/>
<perftest program="java -cp luaj-jse-${version}.jar${path.separator}lib/bcel-5.2.jar lua -b" luaprog="@{luaprog}"/>
</sequential>
</macrodef>
<target name="alltests">
<testcase luaprog="binarytrees.lua 15"/>
<testcase luaprog="fannkuch.lua 10"/>
<testcase luaprog="nbody.lua 1000000"/>
<testcase luaprog="nsieve.lua 9"/>
</target>
<target name="all" depends="alltests"/>
</project>

212
build.xml
View File

@@ -1,212 +0,0 @@
<project default="all">
<property file="version.properties"/>
<property name="jar.name.jme" value="luaj-jme-${version}.jar"/>
<property name="jar.name.jse" value="luaj-jse-${version}.jar"/>
<property name="jar.name.sources" value="luaj-sources-${version}.jar"/>
<target name="clean-build">
<delete dir="build"/>
</target>
<target name="clean" depends="clean-build">
<delete>
<fileset dir="." includes="luaj-*.jar"/>
</delete>
<delete dir="examples/android/bin"/>
<delete dir="examples/android/build"/>
<delete dir="examples/android/gen"/>
<delete dir="examples/android/libs"/>
<delete dir="examples/maven/target"/>
</target>
<import file="build-libs.xml"/>
<target name="parser" depends="javacc-lib">
<java classname="javacc" classpath="lib/javacc.jar">
<arg line="grammar/LuaParser.jj"/>
</java>
</target>
<target name="plain-parser" depends="javacc-lib">
<java dir="src/jse" fork="true" classname="javacc" classpath="lib/javacc.jar">
<arg line="../../grammar/Lua52.jj"/>
</java>
</target>
<target name="compile" depends="wtk-libs,bcel-lib">
<delete dir="build/jme/src"/>
<delete dir="build/jse/src"/>
<mkdir dir="build/jme/src"/>
<mkdir dir="build/jse/src"/>
<mkdir dir="build/jme/classes"/>
<mkdir dir="build/jse/classes"/>
<copy todir="build/jme/src">
<fileset dir="src/core"/>
<fileset dir="src/jme"/>
<filterchain>
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jme ${version}"'/></tokenfilter>
</filterchain>
</copy>
<copy todir="build/jse/src">
<fileset dir="src/core"/>
<filterchain>
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jse ${version}"'/></tokenfilter>
</filterchain>
</copy>
<copy todir="build/jse/src">
<fileset dir="src/jse"/>
<filterchain>
<tokenfilter><replacestring from='&lt;String&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Stat&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Exp&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Name&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Block&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;TableField&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;VarExp&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Exp.VarExp&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Object,String&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Double,String&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Integer,Integer&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Integer,LocalVariableGen&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;Exp,Integer&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;String,byte[]&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;String,Variable&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;LuaValue,String&gt;' to=''/></tokenfilter>
<tokenfilter><replacestring from='&lt;LuaString,String&gt;' to=''/></tokenfilter>
</filterchain>
</copy>
<path id="wtk-libs">
<pathelement path="lib/cldcapi11.jar"/>
<pathelement path="lib/midpapi20.jar"/>
<pathelement path="lib/mmapi.jar"/>
</path>
<javac destdir="build/jme/classes" encoding="utf-8" source="1.3" target="1.2" bootclasspathref="wtk-libs"
debug="on"
srcdir="build/jme/src"/>
<javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
classpath="lib/bcel-5.2.jar"
debug="on"
srcdir="build/jse/src"
excludes="**/script/*,**/Lua2Java*,**/server/*,lua*"/>
<javac destdir="build/jse/classes" encoding="utf-8" source="1.5" target="1.5"
classpath="build/jse/classes"
debug="on"
srcdir="build/jse/src"
includes="**/script/*,**/Lua2Java*,**/server/*"/>
<javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
classpath="build/jse/classes"
debug="on"
srcdir="build/jse/src"
includes="lua*"/>
</target>
<target name="jar-jme" depends="compile">
<jar destfile="${jar.name.jme}" basedir="build/jme/classes"/>
</target>
<target name="jar-jse" depends="compile">
<jar destfile="${jar.name.jse}">
<fileset dir="build/jse/classes"/>
<fileset dir="src/jse/">
<include name="META-INF/services/**"/>
</fileset>
</jar>
</target>
<target name="jar-jse-sources" depends="compile">
<jar destfile="${jar.name.sources}">
<fileset dir="build/jme/src"/>
<fileset dir="build/jse/src"/>
</jar>
</target>
<target name="doc">
<delete dir="docs/api"/>
<mkdir dir="docs/api"/>
<javadoc defaultexcludes="yes"
destdir="docs/api"
author="true"
version="true"
use="true"
windowtitle="Luaj API">
<fileset dir="src/core" defaultexcludes="yes" includes="org/luaj/vm2/*.java,org/luaj/vm2/compiler/LuaC.java,org/luaj/vm2/lib/*.java"/>
<fileset dir="src/jse" defaultexcludes="yes" includes="org/luaj/vm2/lib/jse/*.java,org/luaj/vm2/luajc/LuaJC.java,org/luaj/vm2/server/*.java"/>
<fileset dir="src/jme" defaultexcludes="yes" includes="org/luaj/vm2/lib/jme/*.java"/>
<doctitle><![CDATA[<h1>Luaj API</h1>]]></doctitle>
<bottom><![CDATA[<i>Copyright &#169; 2007-2015 Luaj.org. All Rights Reserved.</i>]]></bottom>
<tag name="todo" scope="all" description="To do:"/>
<group title="Core VM" packages="org.luaj.vm.*"/>
<link offline="true" href="http://sourceforge.net/projects/luaj/" packagelistLoc="C:\tmp"/>
<link href="http://sourceforge.net/projects/luaj/"/>
</javadoc>
</target>
<target name="dist" depends="all,doc">
<delete dir="build/luaj-${version}"/>
<mkdir dir="build/luaj-${version}/src"/>
<mkdir dir="build/luaj-${version}/lib"/>
<copy todir="build/luaj-${version}/src">
<fileset dir="src">
<exclude name="src/test/**"/>
<exclude name="**/antlr/**"/>
<exclude name="**/lst/**"/>
<exclude name="**/JavaCodeGenerator.java"/>
<exclude name="**/LuaJCompiler.java"/>
</fileset>
</copy>
<copy todir="build/luaj-${version}/test">
<fileset dir="test"/>
</copy>
<copy todir="build/luaj-${version}/examples">
<fileset dir="examples">
<include name="android/*.*"/>
<include name="android/assets/**"/>
<include name="android/res/**"/>
<include name="android/src/**"/>
<include name="jme/*.java"/>
<include name="jse/*.java"/>
<include name="lua/*.*"/>
<include name="maven/pom.xml"/>
<include name="maven/src/**"/>
</fileset>
</copy>
<copy todir="build/luaj-${version}/lib">
<fileset dir=".">
<include name="*-${version}.jar"/>
</fileset>
</copy>
<copy todir="build/luaj-${version}">
<fileset dir=".">
<include name="build.xml"/>
<include name="build-libs.xml"/>
<include name="build-coverage.xml"/>
<include name="version.properties"/>
<include name="wtk.xml"/>
<include name="README.html"/>
<include name="names.csv"/>
<include name=".classpath"/>
<include name=".project"/>
</fileset>
</copy>
<copy todir="build/luaj-${version}/docs">
<fileset dir="docs"/>
</copy>
<zip destfile="luaj-${version}.zip"
basedir="build" includes="luaj-${version}/**"/>
</target>
<target name="mvn_install" depends="jar-jse">
<exec executable="mvn">
<arg value="install:install-file"/>
<arg value="-Dfile=${jar.name.jse}"/>
<arg value="-DgroupId=org.luaj"/>
<arg value="-DartifactId=luaj-jse"/>
<arg value="-Dversion=${version}"/>
<arg value="-Dpackaging=jar"/>
</exec>
</target>
<target name="all" depends="clean,jar-jme,jar-jse,jar-jse-sources"/>
</project>

58
core/pom.xml Normal file
View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.openautonomousconnection.luaj</groupId>
<artifactId>parent</artifactId>
<version>0.0.0-STABLE-1.0</version>
</parent>
<artifactId>core</artifactId>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.6.3</version>
<configuration>
<failOnError>false</failOnError>
<failOnWarnings>false</failOnWarnings>
<doclint>none</doclint>
<locale>en_US</locale>
<encoding>UTF-8</encoding>
<docencoding>UTF-8</docencoding>
<charset>UTF-8</charset>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals><goal>jar</goal></goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${maven.compiler.release}</source>
<target>${maven.compiler.release}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -26,11 +26,11 @@ import java.io.InputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.Reader; import java.io.Reader;
import org.luaj.vm2.lib.BaseLib; import org.luaj.vm2.libs.BaseLib;
import org.luaj.vm2.lib.DebugLib; import org.luaj.vm2.libs.DebugLib;
import org.luaj.vm2.lib.IoLib; import org.luaj.vm2.libs.IoLib;
import org.luaj.vm2.lib.PackageLib; import org.luaj.vm2.libs.PackageLib;
import org.luaj.vm2.lib.ResourceFinder; import org.luaj.vm2.libs.ResourceFinder;
/** /**
* Global environment used by luaj. Contains global variables referenced by executing lua. * Global environment used by luaj. Contains global variables referenced by executing lua.
@@ -38,8 +38,8 @@ import org.luaj.vm2.lib.ResourceFinder;
* *
* <h3>Constructing and Initializing Instances</h3> * <h3>Constructing and Initializing Instances</h3>
* Typically, this is constructed indirectly by a call to * Typically, this is constructed indirectly by a call to
* {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or * {@link org.luaj.vm2.libs.jse.JsePlatform#standardGlobals()} or
* {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()}, * {@link org.luaj.vm2.libs.jme.JmePlatform#standardGlobals()},
* and then used to load lua scripts for execution as in the following example. * and then used to load lua scripts for execution as in the following example.
* <pre> {@code * <pre> {@code
* Globals globals = JsePlatform.standardGlobals(); * Globals globals = JsePlatform.standardGlobals();
@@ -89,7 +89,7 @@ import org.luaj.vm2.lib.ResourceFinder;
* </ul> * </ul>
* *
* <h3>Lua Environment Variables</h3> * <h3>Lua Environment Variables</h3>
* When using {@link org.luaj.vm2.lib.jse.JsePlatform} or {@link org.luaj.vm2.lib.jme.JmePlatform}, * When using {@link org.luaj.vm2.libs.jse.JsePlatform} or {@link org.luaj.vm2.libs.jme.JmePlatform},
* these environment variables are created within the Globals. * these environment variables are created within the Globals.
* <ul> * <ul>
* <li>"_G" Pointer to this Globals. * <li>"_G" Pointer to this Globals.
@@ -102,8 +102,8 @@ import org.luaj.vm2.lib.ResourceFinder;
* static immutable resources such as class data and string data. * static immutable resources such as class data and string data.
* <p> * <p>
* *
* @see org.luaj.vm2.lib.jse.JsePlatform * @see org.luaj.vm2.libs.jse.JsePlatform
* @see org.luaj.vm2.lib.jme.JmePlatform * @see org.luaj.vm2.libs.jme.JmePlatform
* @see LuaValue * @see LuaValue
* @see Compiler * @see Compiler
* @see Loader * @see Loader
@@ -179,10 +179,22 @@ public class Globals extends LuaTable {
* @throws LuaError if the file could not be loaded. * @throws LuaError if the file could not be loaded.
*/ */
public LuaValue loadfile(String filename) { public LuaValue loadfile(String filename) {
InputStream is = null;
try { try {
return load(finder.findResource(filename), "@"+filename, "bt", this); is = finder.findResource(filename);
if (is == null) {
return error("cannot open " + filename + ": No such file or directory");
}
return load(is, "@"+filename, "bt", this);
} catch (Exception e) { } catch (Exception e) {
return error("load "+filename+": "+e); return error("load "+filename+": "+e);
} finally {
if (is != null) {
try {
is.close();
} catch (Exception ignored) {
}
}
} }
} }

Binary file not shown.

View File

@@ -44,8 +44,8 @@ import java.io.InputStream;
* This should work regardless of which {@link Globals.Compiler} or {@link Globals.Undumper} * This should work regardless of which {@link Globals.Compiler} or {@link Globals.Undumper}
* have been installed. * have been installed.
* <p> * <p>
* By default, when using {@link org.luaj.vm2.lib.jse.JsePlatform} or * By default, when using {@link org.luaj.vm2.libs.jse.JsePlatform} or
* {@link org.luaj.vm2.lib.jme.JmePlatform} * {@link org.luaj.vm2.libs.jme.JmePlatform}
* to construct globals, the {@link LoadState} default undumper is installed * to construct globals, the {@link LoadState} default undumper is installed
* as the default {@link Globals.Undumper}. * as the default {@link Globals.Undumper}.
* <p> * <p>
@@ -127,8 +127,11 @@ public class LoadState {
public static final String SOURCE_BINARY_STRING = "binary string"; public static final String SOURCE_BINARY_STRING = "binary string";
/** for header of binary files -- this is Lua 5.2 */ /** for header of binary files -- this is Lua 5.5 */
public static final int LUAC_VERSION = 0x52; public static final int LUAC_VERSION = 0x55;
public static final int LUAC_VERSION_54 = 0x54;
public static final int LUAC_VERSION_53 = 0x53;
public static final int LUAC_VERSION_52 = 0x52;
/** for header of binary files -- this is the official format */ /** for header of binary files -- this is the official format */
public static final int LUAC_FORMAT = 0; public static final int LUAC_FORMAT = 0;
@@ -136,6 +139,13 @@ public class LoadState {
/** size of header of binary files */ /** size of header of binary files */
public static final int LUAC_HEADERSIZE = 12; public static final int LUAC_HEADERSIZE = 12;
public static final int LUA_TNUMFLT = LUA_TNUMBER;
public static final int LUA_TSHRSTR = LUA_TSTRING;
public static final int LUA_TNUMINT = LUA_TNUMBER | (1 << 4);
public static final int LUA_TLNGSTR = LUA_TSTRING | (1 << 4);
public static final long LUAC_INT = 0x5678;
public static final double LUAC_NUM = 370.5;
// values read from the header // values read from the header
private int luacVersion; private int luacVersion;
private int luacFormat; private int luacFormat;
@@ -143,6 +153,7 @@ public class LoadState {
private int luacSizeofInt; private int luacSizeofInt;
private int luacSizeofSizeT; private int luacSizeofSizeT;
private int luacSizeofInstruction; private int luacSizeofInstruction;
private int luacSizeofLuaInteger;
private int luacSizeofLuaNumber; private int luacSizeofLuaNumber;
private int luacNumberFormat; private int luacNumberFormat;
@@ -166,6 +177,10 @@ public class LoadState {
globals.undumper = instance; globals.undumper = instance;
} }
private boolean isModernVersion() {
return luacVersion == LUAC_VERSION || luacVersion == LUAC_VERSION_54 || luacVersion == LUAC_VERSION_53;
}
/** Load a 4-byte int value from the input stream /** Load a 4-byte int value from the input stream
* @return the int value laoded. * @return the int value laoded.
**/ **/
@@ -217,6 +232,19 @@ public class LoadState {
* @return the {@link LuaString} value laoded. * @return the {@link LuaString} value laoded.
**/ **/
LuaString loadString() throws IOException { LuaString loadString() throws IOException {
if (isModernVersion()) {
long size = is.readUnsignedByte();
if (size == 0) {
return null;
}
if (size == 0xFFL) {
size = this.luacSizeofSizeT == 8 ? loadInt64() : (loadInt() & 0xffffffffL);
}
int len = (int) size - 1;
byte[] bytes = new byte[len];
is.readFully(bytes, 0, len);
return LuaString.valueUsing(bytes);
}
int size = this.luacSizeofSizeT == 8? (int) loadInt64(): loadInt(); int size = this.luacSizeofSizeT == 8? (int) loadInt64(): loadInt();
if ( size == 0 ) if ( size == 0 )
return null; return null;
@@ -237,12 +265,12 @@ public class LoadState {
int e = (int)((bits >> 52) & 0x7ffL) - 1023; int e = (int)((bits >> 52) & 0x7ffL) - 1023;
if ( e >= 0 && e < 31 ) { if ( e >= 0 && e < 63 ) {
long f = bits & 0xFFFFFFFFFFFFFL; long f = bits & 0xFFFFFFFFFFFFFL;
int shift = 52 - e; int shift = 52 - e;
long intPrecMask = ( 1L << shift ) - 1; long intPrecMask = shift > 0 ? ( 1L << shift ) - 1 : 0;
if ( ( f & intPrecMask ) == 0 ) { if ( shift <= 52 && ( f & intPrecMask ) == 0 ) {
int intValue = (int)( f >> shift ) | ( 1 << e ); long intValue = shift >= 0 ? (f >> shift) | (1L << e) : (f << (-shift)) | (1L << e);
return LuaInteger.valueOf( ( ( bits >> 63 ) != 0 ) ? -intValue : intValue ); return LuaInteger.valueOf( ( ( bits >> 63 ) != 0 ) ? -intValue : intValue );
} }
} }
@@ -256,6 +284,9 @@ public class LoadState {
* @throws IOException if an i/o exception occurs * @throws IOException if an i/o exception occurs
*/ */
LuaValue loadNumber() throws IOException { LuaValue loadNumber() throws IOException {
if (isModernVersion()) {
return LuaValue.valueOf(Double.longBitsToDouble(loadInt64()));
}
if ( luacNumberFormat == NUMBER_FORMAT_INTS_ONLY ) { if ( luacNumberFormat == NUMBER_FORMAT_INTS_ONLY ) {
return LuaInteger.valueOf( loadInt() ); return LuaInteger.valueOf( loadInt() );
} else { } else {
@@ -263,6 +294,10 @@ public class LoadState {
} }
} }
LuaValue loadInteger() throws IOException {
return LuaInteger.valueOf(luacSizeofLuaInteger == 8 ? loadInt64() : loadInt());
}
/** /**
* Load a list of constants from a binary chunk * Load a list of constants from a binary chunk
* @param f the function prototype * @param f the function prototype
@@ -272,7 +307,8 @@ public class LoadState {
int n = loadInt(); int n = loadInt();
LuaValue[] values = n>0? new LuaValue[n]: NOVALUES; LuaValue[] values = n>0? new LuaValue[n]: NOVALUES;
for ( int i=0; i<n; i++ ) { for ( int i=0; i<n; i++ ) {
switch ( is.readByte() ) { int type = is.readByte();
switch ( type ) {
case LUA_TNIL: case LUA_TNIL:
values[i] = LuaValue.NIL; values[i] = LuaValue.NIL;
break; break;
@@ -282,10 +318,14 @@ public class LoadState {
case LUA_TINT: case LUA_TINT:
values[i] = LuaInteger.valueOf( loadInt() ); values[i] = LuaInteger.valueOf( loadInt() );
break; break;
case LUA_TNUMINT:
values[i] = loadInteger();
break;
case LUA_TNUMBER: case LUA_TNUMBER:
values[i] = loadNumber(); values[i] = loadNumber();
break; break;
case LUA_TSTRING: case LUA_TSTRING:
case LUA_TLNGSTR:
values[i] = loadString(); values[i] = loadString();
break; break;
default: default:
@@ -293,8 +333,10 @@ public class LoadState {
} }
} }
f.k = values; f.k = values;
}
n = loadInt(); void loadProtos(Prototype f) throws IOException {
int n = loadInt();
Prototype[] protos = n>0? new Prototype[n]: NOPROTOS; Prototype[] protos = n>0? new Prototype[n]: NOPROTOS;
for ( int i=0; i<n; i++ ) for ( int i=0; i<n; i++ )
protos[i] = loadFunction(f.source); protos[i] = loadFunction(f.source);
@@ -308,7 +350,7 @@ public class LoadState {
for (int i=0; i<n; i++) { for (int i=0; i<n; i++) {
boolean instack = is.readByte() != 0; boolean instack = is.readByte() != 0;
int idx = ((int) is.readByte()) & 0xff; int idx = ((int) is.readByte()) & 0xff;
f.upvalues[i] = new Upvaldesc(null, instack, idx); f.upvalues[i] = new Upvaldesc(null, instack, idx, false);
} }
} }
@@ -318,7 +360,9 @@ public class LoadState {
* @throws IOException if there is an i/o exception * @throws IOException if there is an i/o exception
*/ */
void loadDebug( Prototype f ) throws IOException { void loadDebug( Prototype f ) throws IOException {
if (!isModernVersion()) {
f.source = loadString(); f.source = loadString();
}
f.lineinfo = loadIntArray(); f.lineinfo = loadIntArray();
int n = loadInt(); int n = loadInt();
f.locvars = n>0? new LocVars[n]: NOLOCVARS; f.locvars = n>0? new LocVars[n]: NOLOCVARS;
@@ -326,8 +370,15 @@ public class LoadState {
LuaString varname = loadString(); LuaString varname = loadString();
int startpc = loadInt(); int startpc = loadInt();
int endpc = loadInt(); int endpc = loadInt();
if (luacVersion == LUAC_VERSION || luacVersion == LUAC_VERSION_54) {
int slot = loadInt();
boolean toclose = is.readByte() != 0;
boolean isconst = is.readByte() != 0;
f.locvars[i] = new LocVars(varname, startpc, endpc, slot, toclose, isconst);
} else {
f.locvars[i] = new LocVars(varname, startpc, endpc); f.locvars[i] = new LocVars(varname, startpc, endpc);
} }
}
n = loadInt(); n = loadInt();
for ( int i=0; i<n; i++ ) for ( int i=0; i<n; i++ )
@@ -342,19 +393,33 @@ public class LoadState {
*/ */
public Prototype loadFunction(LuaString p) throws IOException { public Prototype loadFunction(LuaString p) throws IOException {
Prototype f = new Prototype(); Prototype f = new Prototype();
//// this.L.push(f); if (isModernVersion()) {
// f.source = loadString(); f.source = loadString();
// if ( f.source == null ) if (f.source == null)
// f.source = p; f.source = p;
f.linedefined = loadInt(); f.linedefined = loadInt();
f.lastlinedefined = loadInt(); f.lastlinedefined = loadInt();
} else {
f.linedefined = loadInt();
f.lastlinedefined = loadInt();
}
f.numparams = is.readUnsignedByte(); f.numparams = is.readUnsignedByte();
f.is_vararg = is.readUnsignedByte(); f.is_vararg = is.readUnsignedByte();
f.maxstacksize = is.readUnsignedByte(); f.maxstacksize = is.readUnsignedByte();
if (luacVersion == LUAC_VERSION) {
f.varargname = loadString();
}
f.code = loadIntArray(); f.code = loadIntArray();
if (isModernVersion()) {
loadConstants(f);
loadUpvalues(f);
loadProtos(f);
loadDebug(f);
} else {
loadConstants(f); loadConstants(f);
loadUpvalues(f); loadUpvalues(f);
loadDebug(f); loadDebug(f);
}
// TODO: add check here, for debugging purposes, I believe // TODO: add check here, for debugging purposes, I believe
// see ldebug.c // see ldebug.c
@@ -371,16 +436,37 @@ public class LoadState {
public void loadHeader() throws IOException { public void loadHeader() throws IOException {
luacVersion = is.readByte(); luacVersion = is.readByte();
luacFormat = is.readByte(); luacFormat = is.readByte();
if (isModernVersion()) {
for (int i = 0; i < LUAC_TAIL.length; ++i)
if (is.readByte() != LUAC_TAIL[i])
throw new LuaError("unexpected byte in luac data, index=" + i);
luacSizeofInt = is.readUnsignedByte();
luacSizeofSizeT = is.readUnsignedByte();
luacSizeofInstruction = is.readUnsignedByte();
luacSizeofLuaInteger = is.readUnsignedByte();
luacSizeofLuaNumber = is.readUnsignedByte();
luacLittleEndian = true;
long luacInt = luacSizeofLuaInteger == 8 ? loadInt64() : loadInt();
double luacNum = Double.longBitsToDouble(loadInt64());
if (luacInt == Long.reverseBytes(LUAC_INT) || Double.doubleToLongBits(luacNum) == Long.reverseBytes(Double.doubleToLongBits(LUAC_NUM))) {
luacLittleEndian = false;
} else if (luacInt != LUAC_INT || luacNum != LUAC_NUM) {
throw new LuaError("incompatible binary chunk");
}
luacNumberFormat = NUMBER_FORMAT_FLOATS_OR_DOUBLES;
} else {
luacLittleEndian = (0 != is.readByte()); luacLittleEndian = (0 != is.readByte());
luacSizeofInt = is.readByte(); luacSizeofInt = is.readByte();
luacSizeofSizeT = is.readByte(); luacSizeofSizeT = is.readByte();
luacSizeofInstruction = is.readByte(); luacSizeofInstruction = is.readByte();
luacSizeofLuaNumber = is.readByte(); luacSizeofLuaNumber = is.readByte();
luacNumberFormat = is.readByte(); luacNumberFormat = is.readByte();
luacSizeofLuaInteger = luacSizeofLuaNumber;
for (int i=0; i < LUAC_TAIL.length; ++i) for (int i=0; i < LUAC_TAIL.length; ++i)
if (is.readByte() != LUAC_TAIL[i]) if (is.readByte() != LUAC_TAIL[i])
throw new LuaError("Unexpeted byte in luac tail of header, index="+i); throw new LuaError("Unexpeted byte in luac tail of header, index="+i);
} }
}
/** /**
* Load input stream as a lua binary chunk if the first 4 bytes are the lua binary signature. * Load input stream as a lua binary chunk if the first 4 bytes are the lua binary signature.
@@ -403,6 +489,9 @@ public class LoadState {
s.loadHeader(); s.loadHeader();
// check format // check format
if (s.isModernVersion()) {
s.is.readUnsignedByte();
} else {
switch ( s.luacNumberFormat ) { switch ( s.luacNumberFormat ) {
case NUMBER_FORMAT_FLOATS_OR_DOUBLES: case NUMBER_FORMAT_FLOATS_OR_DOUBLES:
case NUMBER_FORMAT_INTS_ONLY: case NUMBER_FORMAT_INTS_ONLY:
@@ -411,6 +500,7 @@ public class LoadState {
default: default:
throw new LuaError("unsupported int size"); throw new LuaError("unsupported int size");
} }
}
return s.loadFunction( LuaString.valueOf(sname) ); return s.loadFunction( LuaString.valueOf(sname) );
} }

Binary file not shown.

View File

@@ -34,6 +34,15 @@ public class LocVars {
/** The instruction offset when the variable goes out of scope */ /** The instruction offset when the variable goes out of scope */
public int endpc; public int endpc;
/** The stack slot used by this local variable. */
public int slot;
/** Whether this local variable should be closed when leaving scope. */
public boolean toclose;
/** Whether this local variable is constant after initialization. */
public boolean isconst;
/** /**
* Construct a LocVars instance. * Construct a LocVars instance.
* @param varname The local variable name * @param varname The local variable name
@@ -41,12 +50,23 @@ public class LocVars {
* @param endpc The instruction offset when the variable goes out of scope * @param endpc The instruction offset when the variable goes out of scope
*/ */
public LocVars(LuaString varname, int startpc, int endpc) { public LocVars(LuaString varname, int startpc, int endpc) {
this(varname, startpc, endpc, -1, false);
}
public LocVars(LuaString varname, int startpc, int endpc, int slot, boolean toclose) {
this(varname, startpc, endpc, slot, toclose, false);
}
public LocVars(LuaString varname, int startpc, int endpc, int slot, boolean toclose, boolean isconst) {
this.varname = varname; this.varname = varname;
this.startpc = startpc; this.startpc = startpc;
this.endpc = endpc; this.endpc = endpc;
this.slot = slot;
this.toclose = toclose;
this.isconst = isconst;
} }
public String tojstring() { public String tojstring() {
return varname+" "+startpc+"-"+endpc; return varname+" "+startpc+"-"+endpc+(toclose? " <close>": "")+(isconst? " <const>": "");
} }
} }

Binary file not shown.

View File

@@ -30,7 +30,7 @@ package org.luaj.vm2;
*/ */
public class Lua { public class Lua {
/** version is supplied by ant build task */ /** version is supplied by ant build task */
public static final String _VERSION = "Luaj 0.0"; public static final String _VERSION = "Lua 5.5";
/** use return values from previous op */ /** use return values from previous op */
public static final int LUA_MULTRET = -1; public static final int LUA_MULTRET = -1;
@@ -200,39 +200,46 @@ public class Lua {
public static final int OP_SUB = 14; /* A B C R(A) := RK(B) - RK(C) */ public static final int OP_SUB = 14; /* A B C R(A) := RK(B) - RK(C) */
public static final int OP_MUL = 15; /* A B C R(A) := RK(B) * RK(C) */ public static final int OP_MUL = 15; /* A B C R(A) := RK(B) * RK(C) */
public static final int OP_DIV = 16; /* A B C R(A) := RK(B) / RK(C) */ public static final int OP_DIV = 16; /* A B C R(A) := RK(B) / RK(C) */
public static final int OP_MOD = 17; /* A B C R(A) := RK(B) % RK(C) */ public static final int OP_IDIV = 17; /* A B C R(A) := RK(B) // RK(C) */
public static final int OP_POW = 18; /* A B C R(A) := RK(B) ^ RK(C) */ public static final int OP_BAND = 18; /* A B C R(A) := RK(B) & RK(C) */
public static final int OP_UNM = 19; /* A B R(A) := -R(B) */ public static final int OP_BOR = 19; /* A B C R(A) := RK(B) | RK(C) */
public static final int OP_NOT = 20; /* A B R(A) := not R(B) */ public static final int OP_BXOR = 20; /* A B C R(A) := RK(B) ~ RK(C) */
public static final int OP_LEN = 21; /* A B R(A) := length of R(B) */ public static final int OP_SHL = 21; /* A B C R(A) := RK(B) << RK(C) */
public static final int OP_SHR = 22; /* A B C R(A) := RK(B) >> RK(C) */
public static final int OP_MOD = 23; /* A B C R(A) := RK(B) % RK(C) */
public static final int OP_POW = 24; /* A B C R(A) := RK(B) ^ RK(C) */
public static final int OP_UNM = 25; /* A B R(A) := -R(B) */
public static final int OP_BNOT = 26; /* A B R(A) := ~R(B) */
public static final int OP_NOT = 27; /* A B R(A) := not R(B) */
public static final int OP_LEN = 28; /* A B R(A) := length of R(B) */
public static final int OP_CONCAT = 22; /* A B C R(A) := R(B).. ... ..R(C) */ public static final int OP_CONCAT = 29; /* 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 = 30; /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
public static final int OP_EQ = 24; /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ public static final int OP_EQ = 31; /* 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 = 32; /* 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 = 33; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
public static final int OP_TEST = 27; /* A C if not (R(A) <=> C) then pc++ */ public static final int OP_TEST = 34; /* A C if not (R(A) <=> C) then pc++ */
public static final int OP_TESTSET = 28; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ public static final int OP_TESTSET = 35; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
public static final int OP_CALL = 29; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ public static final int OP_CALL = 36; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
public static final int OP_TAILCALL = 30; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ public static final int OP_TAILCALL = 37; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
public static final int OP_RETURN = 31; /* A B return R(A), ... ,R(A+B-2) (see note) */ public static final int OP_RETURN = 38; /* A B return R(A), ... ,R(A+B-2) (see note) */
public static final int OP_FORLOOP = 32; /* A sBx R(A)+=R(A+2); public static final int OP_FORLOOP = 39; /* A sBx R(A)+=R(A+2);
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/ if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
public static final int OP_FORPREP = 33; /* A sBx R(A)-=R(A+2); pc+=sBx */ public static final int OP_FORPREP = 40; /* A sBx R(A)-=R(A+2); pc+=sBx */
public static final int OP_TFORCALL = 34; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */ public static final int OP_TFORCALL = 41; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
public static final int OP_TFORLOOP = 35; /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */ public static final int OP_TFORLOOP = 42; /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */
public static final int OP_SETLIST = 36; /* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ public static final int OP_SETLIST = 43; /* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
public static final int OP_CLOSURE = 37; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ public static final int OP_CLOSURE = 44; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
public static final int OP_VARARG = 38; /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ public static final int OP_VARARG = 45; /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
public static final int OP_EXTRAARG = 39; /* Ax extra (larger) argument for previous opcode */ public static final int OP_EXTRAARG = 46; /* Ax extra (larger) argument for previous opcode */
public static final int NUM_OPCODES = OP_EXTRAARG + 1; public static final int NUM_OPCODES = OP_EXTRAARG + 1;
@@ -297,9 +304,16 @@ public class Lua {
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SUB */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SUB */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MUL */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MUL */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_DIV */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_DIV */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_IDIV */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_BAND */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_BOR */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_BXOR */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SHL */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_SHR */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MOD */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_MOD */
(0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_POW */ (0<<7) | (1<<6) | (OpArgK<<4) | (OpArgK<<2) | (iABC), /* OP_POW */
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_UNM */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_UNM */
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_BNOT */
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_NOT */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_NOT */
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_LEN */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgN<<2) | (iABC), /* OP_LEN */
(0<<7) | (1<<6) | (OpArgR<<4) | (OpArgR<<2) | (iABC), /* OP_CONCAT */ (0<<7) | (1<<6) | (OpArgR<<4) | (OpArgR<<2) | (iABC), /* OP_CONCAT */

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,768 @@
/*******************************************************************************
* 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;
import org.luaj.vm2.libs.DebugLib.CallFrame;
import java.util.ArrayList;
import java.util.List;
/**
* Extension of {@link LuaFunction} which executes lua bytecode.
* <p>
* A {@link LuaClosure} is a combination of a {@link Prototype}
* and a {@link LuaValue} to use as an environment for execution.
* Normally the {@link LuaValue} is a {@link Globals} in which case the environment
* will contain standard lua libraries.
*
* <p>
* There are three main ways {@link LuaClosure} instances are created:
* <ul>
* <li>Construct an instance using {@link #LuaClosure(Prototype, LuaValue)}</li>
* <li>Construct it indirectly by loading a chunk via {@link Globals#load(java.io.Reader, String)}
* <li>Execute the lua bytecode {@link Lua#OP_CLOSURE} as part of bytecode processing
* </ul>
* <p>
* To construct it directly, the {@link Prototype} is typically created via a compiler such as
* {@link org.luaj.vm2.compiler.LuaC}:
* <pre> {@code
* String script = "print( 'hello, world' )";
* InputStream is = new ByteArrayInputStream(script.getBytes());
* Prototype p = LuaC.instance.compile(is, "script");
* LuaValue globals = JsePlatform.standardGlobals();
* LuaClosure f = new LuaClosure(p, globals);
* f.call();
* }</pre>
* <p>
* To construct it indirectly, the {@link Globals#load(java.io.Reader, String)} method may be used:
* <pre> {@code
* Globals globals = JsePlatform.standardGlobals();
* LuaFunction f = globals.load(new StringReader(script), "script");
* LuaClosure c = f.checkclosure(); // This may fail if LuaJC is installed.
* c.call();
* }</pre>
* <p>
* In this example, the "checkclosure()" may fail if direct lua-to-java-bytecode
* compiling using LuaJC is installed, because no LuaClosure is created in that case
* and the value returned is a {@link LuaFunction} but not a {@link LuaClosure}.
* <p>
* Since a {@link LuaClosure} is a {@link LuaFunction} which is a {@link LuaValue},
* all the value operations can be used directly such as:
* <ul>
* <li>{@link LuaValue#call()}</li>
* <li>{@link LuaValue#call(LuaValue)}</li>
* <li>{@link LuaValue#invoke()}</li>
* <li>{@link LuaValue#invoke(Varargs)}</li>
* <li>{@link LuaValue#method(String)}</li>
* <li>{@link LuaValue#method(String,LuaValue)}</li>
* <li>{@link LuaValue#invokemethod(String)}</li>
* <li>{@link LuaValue#invokemethod(String,Varargs)}</li>
* <li> ...</li>
* </ul>
* @see LuaValue
* @see LuaFunction
* @see LuaValue#isclosure()
* @see LuaValue#checkclosure()
* @see LuaValue#optclosure(LuaClosure)
* @see LoadState
* @see Globals#compiler
*/
public class LuaClosure extends LuaFunction implements PrototypeProvider {
private static final UpValue[] NOUPVALUES = new UpValue[0];
private static final boolean[] NOCLOSEVARS = new boolean[0];
public final Prototype p;
public UpValue[] upValues;
final Globals globals;
/** Create a closure around a Prototype with a specific environment.
* If the prototype has upvalues, the environment will be written into the first upvalue.
* @param p the Prototype to construct this Closure for.
* @param env the environment to associate with the closure.
*/
public LuaClosure(Prototype p, LuaValue env) {
this.p = p;
this.initupvalue1(env);
globals = env instanceof Globals? (Globals) env: null;
}
public Prototype prototype() {
return p;
}
public void initupvalue1(LuaValue env) {
if (p.upvalues == null || p.upvalues.length == 0)
this.upValues = NOUPVALUES;
else {
this.upValues = new UpValue[p.upvalues.length];
this.upValues[0] = new UpValue(new LuaValue[] {env}, 0);
}
}
public boolean isclosure() {
return true;
}
public LuaClosure optclosure(LuaClosure defval) {
return this;
}
public LuaClosure checkclosure() {
return this;
}
public String tojstring() {
return "function: " + p.toString();
}
private List<LuaValue[]> stackPool = new ArrayList<>();
private LuaValue[] getNewStack() {
if (stackPool.isEmpty()) {
return getNewStackRaw();
} else {
return stackPool.remove(stackPool.size() - 1);
}
}
private LuaValue[] getNewStackRaw() {
int max = p.maxstacksize;
LuaValue[] stack = new LuaValue[max];
System.arraycopy(NILS, 0, stack, 0, max);
return stack;
}
private void releaseStack(LuaValue[] stack) {
System.arraycopy(NILS, 0, stack, 0, stack.length);
stackPool.add(stack);
}
public final LuaValue call() {
LuaValue[] stack = getNewStack();
LuaValue result = execute(stack,NONE).arg1();
releaseStack(stack);
return result;
}
public final LuaValue call(LuaValue arg) {
LuaValue[] stack = getNewStack();
LuaValue result;
switch ( p.numparams ) {
default:
stack[0]=arg;
result = execute(stack,NONE).arg1();
break;
case 0:
result = execute(stack,arg).arg1();
break;
}
releaseStack(stack);
return result;
}
public final LuaValue call(LuaValue arg1, LuaValue arg2) {
LuaValue[] stack = getNewStack();
LuaValue result;
switch ( p.numparams ) {
default:
stack[0]=arg1;
stack[1]=arg2;
result = execute(stack,NONE).arg1();
break;
case 1:
stack[0]=arg1;
result = execute(stack,arg2).arg1();
break;
case 0:
result = execute(stack,p.is_vararg!=0 ? varargsOf(arg1,arg2) : NONE).arg1();
break;
}
releaseStack(stack);
return result;
}
public final LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
LuaValue[] stack = getNewStack();
LuaValue result;
switch ( p.numparams ) {
default:
stack[0]=arg1;
stack[1]=arg2;
stack[2]=arg3;
result = execute(stack,NONE).arg1();
break;
case 2:
stack[0]=arg1;
stack[1]=arg2;
result = execute(stack,arg3).arg1();
break;
case 1:
stack[0]=arg1;
result = execute(stack,p.is_vararg!=0 ? varargsOf(arg2,arg3) : NONE).arg1();
break;
case 0:
result = execute(stack,p.is_vararg!=0 ? varargsOf(arg1,arg2,arg3) : NONE).arg1();
break;
}
releaseStack(stack);
return result;
}
public final Varargs invoke(Varargs varargs) {
return onInvoke(varargs).eval();
}
public final Varargs onInvoke(Varargs varargs) {
LuaValue[] stack = getNewStack();
for ( int i=0; i<p.numparams; i++ )
stack[i] = varargs.arg(i+1);
Varargs result = execute(stack,p.is_vararg!=0 ? varargs.subargs(p.numparams+1) : NONE);
if (result instanceof LuaValue) {
releaseStack(stack);
}
return result;
}
protected Varargs execute( LuaValue[] stack, Varargs varargs ) {
// loop through instructions
int i,a,b,c,pc=0,top=0;
LuaValue o;
Varargs v = NONE;
int[] code = p.code;
LuaValue[] k = p.k;
// upvalues are only possible when closures create closures
// TODO: use linked list.
UpValue[] openups = p.p.length>0? new UpValue[stack.length]: null;
boolean[] closedLocals = hasToCloseLocals()? new boolean[stack.length]: NOCLOSEVARS;
if (p.varargname != null && p.numparams < stack.length)
stack[p.numparams] = packVarargs(varargs);
// allow for debug hooks
if (globals != null && globals.debuglib != null)
globals.debuglib.onCall( this, varargs, stack );
// process instructions
try {
for (; true; ++pc) {
if (Thread.currentThread().isInterrupted()) {
throw new LuaError("interrupted");
}
prepareToCloseLocals(stack, closedLocals, pc);
if (globals != null && globals.debuglib != null)
globals.debuglib.onInstruction( pc, v, top );
// pull out instruction
i = code[pc];
a = ((i>>6) & 0xff);
// process the op code
switch ( i & 0x3f ) {
case Lua.OP_MOVE:/* A B R(A):= R(B) */
stack[a] = stack[i>>>23];
continue;
case Lua.OP_LOADK:/* A Bx R(A):= Kst(Bx) */
stack[a] = k[i>>>14];
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++ */
stack[a] = (i>>>23!=0)? LuaValue.TRUE: LuaValue.FALSE;
if ((i&(0x1ff<<14)) != 0)
++pc; /* skip next instruction (if C) */
continue;
case Lua.OP_LOADNIL: /* A B R(A):= ...:= R(A+B):= nil */
for ( b=i>>>23; b-->=0; )
stack[a++] = LuaValue.NIL;
continue;
case Lua.OP_GETUPVAL: /* A B R(A):= UpValue[B] */
stack[a] = upValues[i>>>23].getValue();
continue;
case Lua.OP_GETTABUP: /* A B C R(A) := UpValue[B][RK(C)] */
stack[a] = upValues[i>>>23].getValue().get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_GETTABLE: /* A B C R(A):= R(B)[RK(C)] */
stack[a] = stack[i>>>23].get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_SETTABUP: /* A B C UpValue[A][RK(B)] := RK(C) */
upValues[a].getValue().set(((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]), (c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_SETUPVAL: /* A B UpValue[B]:= R(A) */
upValues[i>>>23].setValue(stack[a]);
continue;
case Lua.OP_SETTABLE: /* A B C R(A)[RK(B)]:= RK(C) */
stack[a].set(((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]), (c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_NEWTABLE: /* A B C R(A):= {} (size = B,C) */
stack[a] = new LuaTable(i>>>23,(i>>14)&0x1ff);
continue;
case Lua.OP_SELF: /* A B C R(A+1):= R(B): R(A):= R(B)[RK(C)] */
stack[a+1] = (o = stack[i>>>23]);
stack[a] = o.get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_ADD: /* A B C R(A):= RK(B) + RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).add((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_SUB: /* A B C R(A):= RK(B) - RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).sub((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_MUL: /* A B C R(A):= RK(B) * RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mul((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_DIV: /* A B C R(A):= RK(B) / RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).div((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_IDIV: /* A B C R(A):= RK(B) // RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).idiv((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_BAND: /* A B C R(A):= RK(B) & RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).band((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_BOR: /* A B C R(A):= RK(B) | RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).bor((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_BXOR: /* A B C R(A):= RK(B) ~ RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).bxor((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_SHL: /* A B C R(A):= RK(B) << RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).shl((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_SHR: /* A B C R(A):= RK(B) >> RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).shr((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_MOD: /* A B C R(A):= RK(B) % RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mod((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_POW: /* A B C R(A):= RK(B) ^ RK(C) */
stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).pow((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
continue;
case Lua.OP_UNM: /* A B R(A):= -R(B) */
stack[a] = stack[i>>>23].neg();
continue;
case Lua.OP_BNOT: /* A B R(A):= ~R(B) */
stack[a] = stack[i>>>23].bnot();
continue;
case Lua.OP_NOT: /* A B R(A):= not R(B) */
stack[a] = stack[i>>>23].not();
continue;
case Lua.OP_LEN: /* A B R(A):= length of R(B) */
stack[a] = stack[i>>>23].len();
continue;
case Lua.OP_CONCAT: /* A B C R(A):= R(B).. ... ..R(C) */
b = i>>>23;
c = (i>>14)&0x1ff;
{
if ( c > b+1 ) {
Buffer sb = stack[c].buffer();
while ( --c>=b )
sb.concatTo(stack[c]);
stack[a] = sb.value();
} else {
stack[a] = stack[c-1].concat(stack[c]);
}
}
continue;
case Lua.OP_JMP: /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
pc += (i>>>14)-0x1ffff;
if (a > 0) {
--a;
if (openups != null) {
for (b = openups.length; --b>=0; )
if (openups[b] != null && openups[b].index >= a) {
openups[b].close();
openups[b] = null;
}
}
closeLocals(stack, closedLocals, a, pc + 1, LuaValue.NIL);
}
continue;
case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).eq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
++pc;
continue;
case Lua.OP_LT: /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lt_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
++pc;
continue;
case Lua.OP_LE: /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
if ( ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).lteq_b((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]) != (a!=0) )
++pc;
continue;
case Lua.OP_TEST: /* A C if not (R(A) <=> C) then pc++ */
if ( stack[a].toboolean() != ((i&(0x1ff<<14))!=0) )
++pc;
continue;
case Lua.OP_TESTSET: /* A B C if (R(B) <=> C) then R(A):= R(B) else pc++ */
/* note: doc appears to be reversed */
if ( (o=stack[i>>>23]).toboolean() != ((i&(0x1ff<<14))!=0) )
++pc;
else
stack[a] = o; // TODO: should be sBx?
continue;
case Lua.OP_CALL: /* A B C R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */
switch ( i & (Lua.MASK_B | Lua.MASK_C) ) {
case (1<<Lua.POS_B) | (0<<Lua.POS_C): v=stack[a].invoke(NONE); top=a+v.narg(); continue;
case (2<<Lua.POS_B) | (0<<Lua.POS_C): v=stack[a].invoke(stack[a+1]); top=a+v.narg(); continue;
case (1<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(); continue;
case (2<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1]); continue;
case (3<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1],stack[a+2]); continue;
case (4<<Lua.POS_B) | (1<<Lua.POS_C): stack[a].call(stack[a+1],stack[a+2],stack[a+3]); continue;
case (1<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(); continue;
case (2<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1]); continue;
case (3<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1],stack[a+2]); continue;
case (4<<Lua.POS_B) | (2<<Lua.POS_C): stack[a] = stack[a].call(stack[a+1],stack[a+2],stack[a+3]); continue;
default:
b = i>>>23;
c = (i>>14)&0x1ff;
v = stack[a].invoke(b>0?
varargsOf(stack, a+1, b-1): // exact arg count
varargsOf(stack, a+1, top-v.narg()-(a+1), v)); // from prev top
if ( c > 0 ) {
v.copyto(stack, a, c-1);
v = NONE;
} else {
top = a + v.narg();
v = v.dealias();
}
continue;
}
case Lua.OP_TAILCALL: /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
switch ( i & Lua.MASK_B ) {
case (1<<Lua.POS_B): return new TailcallVarargs(stack[a], NONE);
case (2<<Lua.POS_B): return new TailcallVarargs(stack[a], stack[a+1]);
case (3<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2]));
case (4<<Lua.POS_B): return new TailcallVarargs(stack[a], varargsOf(stack[a+1],stack[a+2],stack[a+3]));
default:
b = i>>>23;
v = b>0?
varargsOf(stack,a+1,b-1): // exact arg count
varargsOf(stack, a+1, top-v.narg()-(a+1), v); // from prev top
return new TailcallVarargs( stack[a], v );
}
case Lua.OP_RETURN: /* A B return R(A), ... ,R(A+B-2) (see note) */
closeLocals(stack, closedLocals, 0, p.code.length, LuaValue.NIL);
b = i>>>23;
switch ( b ) {
case 0: return varargsOf(stack, a, top-v.narg()-a, v);
case 1: return NONE;
case 2: return stack[a];
default:
return varargsOf(stack, a, b-1);
}
case Lua.OP_FORLOOP: /* A sBx R(A)+=R(A+2): if R(A) <?= R(A+1) then { pc+=sBx: R(A+3)=R(A) }*/
{
LuaValue limit = stack[a + 1];
LuaValue step = stack[a + 2];
LuaValue idx = stack[a].add(step);
if (step.gt_b(0)? idx.lteq_b(limit): idx.gteq_b(limit)) {
stack[a] = idx;
stack[a + 3] = idx;
pc += (i>>>14)-0x1ffff;
}
}
continue;
case Lua.OP_FORPREP: /* A sBx R(A)-=R(A+2): pc+=sBx */
{
LuaValue init = stack[a].checknumber("'for' initial value must be a number");
LuaValue limit = stack[a + 1].checknumber("'for' limit must be a number");
LuaValue step = stack[a + 2].checknumber("'for' step must be a number");
stack[a] = init.sub(step);
stack[a + 1] = limit;
stack[a + 2] = step;
pc += (i>>>14)-0x1ffff;
}
continue;
case Lua.OP_TFORCALL: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
v = stack[a].invoke(varargsOf(stack[a+1],stack[a+2]));
c = (i>>14) & 0x1ff;
while (--c >= 0)
stack[a+3+c] = v.arg(c+1);
v = NONE;
continue;
case Lua.OP_TFORLOOP: /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx */
if (!stack[a+1].isnil()) { /* continue loop? */
stack[a] = stack[a+1]; /* save control varible. */
pc += (i>>>14)-0x1ffff;
}
continue;
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
{
if ( (c=(i>>14)&0x1ff) == 0 )
c = code[++pc];
int offset = (c-1) * Lua.LFIELDS_PER_FLUSH;
o = stack[a];
if ( (b=i>>>23) == 0 ) {
b = top - a - 1;
int m = b - v.narg();
int j=1;
for ( ;j<=m; j++ )
o.set(offset+j, stack[a + j]);
for ( ;j<=b; j++ )
o.set(offset+j, v.arg(j-m));
} else {
o.presize( offset + b );
for (int j=1; j<=b; j++)
o.set(offset+j, stack[a + j]);
}
}
continue;
case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx]) */
{
Prototype newp = p.p[i>>>14];
LuaClosure ncl = new LuaClosure(newp, globals);
Upvaldesc[] uv = newp.upvalues;
for ( int j=0, nup=uv.length; j<nup; ++j ) {
if (uv[j].instack) /* upvalue refes to local variable? */
ncl.upValues[j] = findupval(stack, uv[j].idx, openups);
else /* get upvalue from enclosing function */
ncl.upValues[j] = upValues[uv[j].idx];
}
stack[a] = ncl;
}
continue;
case Lua.OP_VARARG: /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
b = i>>>23;
if ( b == 0 ) {
top = a + (b = varargs.narg());
v = varargs;
} else {
for ( int j=1; j<b; ++j )
stack[a+j-1] = varargs.arg(j);
}
continue;
case Lua.OP_EXTRAARG:
throw new java.lang.IllegalArgumentException("Uexecutable opcode: OP_EXTRAARG");
default:
throw new java.lang.IllegalArgumentException("Illegal opcode: " + (i & 0x3f));
}
}
} catch ( LuaError le ) {
if (le.traceback == null)
processErrorHooks(le, p, pc);
closeLocals(stack, closedLocals, 0, p.code.length, le.getMessageObject());
throw le;
} catch ( Exception e ) {
LuaError le = new LuaError(e);
processErrorHooks(le, p, pc);
closeLocals(stack, closedLocals, 0, p.code.length, le.getMessageObject());
throw le;
} finally {
closeLocals(stack, closedLocals, 0, p.code.length, LuaValue.NIL);
if ( openups != null )
for ( int u=openups.length; --u>=0; )
if ( openups[u] != null )
openups[u].close();
if (globals != null && globals.debuglib != null)
globals.debuglib.onReturn();
}
}
private LuaTable packVarargs(Varargs varargs) {
LuaTable table = LuaValue.tableOf(varargs, 1);
table.set("n", LuaValue.valueOf(varargs.narg()));
return table;
}
private boolean hasToCloseLocals() {
if (p.locvars == null)
return false;
for (int i = 0; i < p.locvars.length; i++) {
LocVars local = p.locvars[i];
if (local != null && local.toclose)
return true;
}
return false;
}
private void prepareToCloseLocals(LuaValue[] stack, boolean[] closedLocals, int pc) {
if (closedLocals.length == 0 || p.locvars == null)
return;
for (int i = 0; i < p.locvars.length; i++) {
LocVars local = p.locvars[i];
if (local == null || !local.toclose || local.slot < 0 || local.startpc != pc)
continue;
if (local.slot < closedLocals.length)
closedLocals[local.slot] = false;
checkClosable(local, stack[local.slot]);
}
}
private void closeLocals(LuaValue[] stack, boolean[] closedLocals, int minSlot, int closePcExclusive, LuaValue err) {
if (closedLocals.length == 0 || p.locvars == null)
return;
for (int i = p.locvars.length - 1; i >= 0; i--) {
LocVars local = p.locvars[i];
if (local == null || !local.toclose || local.slot < 0 || local.slot < minSlot)
continue;
if (local.slot >= closedLocals.length || closedLocals[local.slot])
continue;
if (local.endpc > closePcExclusive)
continue;
closedLocals[local.slot] = true;
LuaValue value = stack[local.slot];
if (value == null || value == LuaValue.FALSE)
continue;
LuaValue close = value.metatag(LuaValue.CLOSE);
if (!close.isnil())
close.call(value, err.isnil() ? LuaValue.NIL : err);
}
}
private void checkClosable(LocVars local, LuaValue value) {
if (value == null || value == LuaValue.FALSE)
return;
if (!value.metatag(LuaValue.CLOSE).isnil())
return;
throw new LuaError("variable '" + local.varname.tojstring() + "' got a non-closable value");
}
/**
* Run the error hook if there is one
* @param msg the message to use in error hook processing.
* */
LuaValue errorHook(LuaValue msgobj, String msg, int level) {
if (globals == null ) return LuaValue.valueOf(msg);
final LuaThread r = globals.running;
if (r.errorfunc == null)
return LuaValue.valueOf(globals.debuglib != null?
msg + "\n" + globals.debuglib.traceback(level):
msg);
final LuaValue e = r.errorfunc;
r.errorfunc = null;
try {
return e.call(msgobj != null ? msgobj : LuaValue.NIL);
} catch ( Throwable t ) {
return LuaValue.valueOf("error in error handling");
} finally {
r.errorfunc = e;
}
}
private void processErrorHooks(LuaError le, Prototype p, int pc) {
String file = "?";
int line = -1;
{
CallFrame frame = null;
if (globals != null && globals.debuglib != null) {
frame = globals.debuglib.getCallFrame(le.level);
if (frame != null) {
String src = frame.shortsource();
file = src != null ? src : "?";
line = frame.currentline();
}
}
if (frame == null) {
file = p.source != null? p.source.tojstring(): "?";
line = p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length ? p.lineinfo[pc] : -1;
}
}
le.fileline = file + ":" + line;
LuaValue error = errorHook(le.getMessageObject(), le.getMessage(), le.level);
le.setMessageObject(error);
le.traceback = error != null ? error.tojstring() : null;
}
private UpValue findupval(LuaValue[] stack, short idx, UpValue[] openups) {
final int n = openups.length;
for (int i = 0; i < n; ++i)
if (openups[i] != null && openups[i].index == idx)
return openups[i];
for (int i = 0; i < n; ++i)
if (openups[i] == null)
return openups[i] = new UpValue(stack, idx);
error("No space for upvalue");
return null;
}
protected LuaValue getUpvalue(int i) {
return upValues[i].getValue();
}
protected void setUpvalue(int i, LuaValue v) {
upValues[i].setValue(v);
}
public String name() {
return "<"+p.shortsource()+":"+p.linedefined+">";
}
}

Binary file not shown.

View File

@@ -21,7 +21,7 @@
******************************************************************************/ ******************************************************************************/
package org.luaj.vm2; package org.luaj.vm2;
import org.luaj.vm2.lib.MathLib; import org.luaj.vm2.libs.MathLib;
/** /**
* Extension of {@link LuaNumber} which can hold a Java double as its value. * Extension of {@link LuaNumber} which can hold a Java double as its value.
@@ -75,8 +75,13 @@ public class LuaDouble extends LuaNumber {
final double v; final double v;
public static LuaNumber valueOf(double d) { public static LuaNumber valueOf(double d) {
int id = (int) d; if (!Double.isNaN(d) && !Double.isInfinite(d) && d >= Long.MIN_VALUE && d <= Long.MAX_VALUE) {
return d==id? (LuaNumber) LuaInteger.valueOf(id): (LuaNumber) new LuaDouble(d); long ld = (long) d;
if (d == ld) {
return LuaInteger.valueOf(ld);
}
}
return new LuaDouble(d);
} }
/** Don't allow ints to be boxed by DoubleValues */ /** Don't allow ints to be boxed by DoubleValues */
@@ -103,13 +108,14 @@ public class LuaDouble extends LuaNumber {
public double optdouble(double defval) { return v; } public double optdouble(double defval) { return v; }
public int optint(int defval) { return (int) (long) v; } public int optint(int defval) { return (int) (long) v; }
public LuaInteger optinteger(LuaInteger defval) { return LuaInteger.valueOf((int) (long)v); } public LuaInteger optinteger(LuaInteger defval) { return islong()? LuaInteger.valueOf((long) v): defval; }
public long optlong(long defval) { return (long) v; } public long optlong(long defval) { return (long) v; }
public LuaInteger checkinteger() { return LuaInteger.valueOf( (int) (long) v ); } public LuaInteger checkinteger() { if (!islong()) argerror("integer"); return LuaInteger.valueOf((long) v); }
// unary operators // unary operators
public LuaValue neg() { return valueOf(-v); } public LuaValue neg() { return valueOf(-v); }
public LuaValue bnot() { if (!islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(~((long) v)); }
// object equality, used for key comparison // object equality, used for key comparison
public boolean equals(Object o) { return o instanceof LuaDouble? ((LuaDouble)o).v == v: false; } public boolean equals(Object o) { return o instanceof LuaDouble? ((LuaDouble)o).v == v: false; }
@@ -122,6 +128,7 @@ public class LuaDouble extends LuaNumber {
public boolean raweq( LuaValue val ) { return val.raweq(v); } public boolean raweq( LuaValue val ) { return val.raweq(v); }
public boolean raweq( double val ) { return v == val; } public boolean raweq( double val ) { return v == val; }
public boolean raweq( int val ) { return v == val; } public boolean raweq( int val ) { return v == val; }
public boolean raweq( long val ) { return v == val; }
// basic binary arithmetic // basic binary arithmetic
public LuaValue add( LuaValue rhs ) { return rhs.add(v); } public LuaValue add( LuaValue rhs ) { return rhs.add(v); }
@@ -139,9 +146,18 @@ public class LuaDouble extends LuaNumber {
public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs,v); } public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs,v); }
public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs,v); } public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs,v); }
public LuaValue div( LuaValue rhs ) { return rhs.divInto(v); } public LuaValue div( LuaValue rhs ) { return rhs.divInto(v); }
public LuaValue idiv( LuaValue rhs ) { return rhs.idivInto(v); }
public LuaValue div( double rhs ) { return LuaDouble.ddiv(v,rhs); } public LuaValue div( double rhs ) { return LuaDouble.ddiv(v,rhs); }
public LuaValue div( int rhs ) { return LuaDouble.ddiv(v,rhs); } public LuaValue div( int rhs ) { return LuaDouble.ddiv(v,rhs); }
public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs,v); } public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs,v); }
public LuaValue idiv( double rhs ) { return LuaDouble.didiv(v,rhs); }
public LuaValue idiv( int rhs ) { return LuaDouble.didiv(v,rhs); }
public LuaValue idivInto( double lhs ) { return LuaDouble.didiv(lhs,v); }
public LuaValue band( LuaValue rhs ) { if (!islong()) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.band(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(((long) v) & n.tolong()); }
public LuaValue bor( LuaValue rhs ) { if (!islong()) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.bor(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(((long) v) | n.tolong()); }
public LuaValue bxor( LuaValue rhs ) { if (!islong()) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.bxor(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(((long) v) ^ n.tolong()); }
public LuaValue shl( LuaValue rhs ) { if (!islong()) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.shl(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(LuaInteger.luaShiftLeft((long) v, n.tolong())); }
public LuaValue shr( LuaValue rhs ) { if (!islong()) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.shr(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(LuaInteger.luaShiftRight((long) v, n.tolong())); }
public LuaValue mod( LuaValue rhs ) { return rhs.modFrom(v); } public LuaValue mod( LuaValue rhs ) { return rhs.modFrom(v); }
public LuaValue mod( double rhs ) { return LuaDouble.dmod(v,rhs); } public LuaValue mod( double rhs ) { return LuaDouble.dmod(v,rhs); }
public LuaValue mod( int rhs ) { return LuaDouble.dmod(v,rhs); } public LuaValue mod( int rhs ) { return LuaDouble.dmod(v,rhs); }
@@ -159,6 +175,10 @@ public class LuaDouble extends LuaNumber {
return rhs!=0? valueOf( lhs / rhs ): lhs>0? POSINF: lhs==0? NAN: NEGINF; return rhs!=0? valueOf( lhs / rhs ): lhs>0? POSINF: lhs==0? NAN: NEGINF;
} }
public static LuaValue didiv(double lhs, double rhs) {
return valueOf(Math.floor(ddiv_d(lhs, rhs)));
}
/** Divide two double numbers according to lua math, and return a double result. /** Divide two double numbers according to lua math, and return a double result.
* @param lhs Left-hand-side of the division. * @param lhs Left-hand-side of the division.
* @param rhs Right-hand-side of the division. * @param rhs Right-hand-side of the division.

Binary file not shown.

View File

@@ -76,6 +76,10 @@ public class LuaError extends RuntimeException {
return m != null ? LuaValue.valueOf(m): null; return m != null ? LuaValue.valueOf(m): null;
} }
public void setMessageObject(LuaValue messageObject) {
this.object = messageObject;
}
/** Construct LuaError when a program exception occurs. /** Construct LuaError when a program exception occurs.
* <p> * <p>
* All errors generated from lua code should throw LuaError(String) instead. * All errors generated from lua code should throw LuaError(String) instead.

Binary file not shown.

View File

@@ -25,14 +25,14 @@ package org.luaj.vm2;
/** /**
* Base class for functions implemented in Java. * Base class for functions implemented in Java.
* <p> * <p>
* Direct subclass include {@link org.luaj.vm2.lib.LibFunction} * Direct subclass include {@link org.luaj.vm2.libs.LibFunction}
* which is the base class for * which is the base class for
* all built-in library functions coded in Java, * all built-in library functions coded in Java,
* and {@link LuaClosure}, which represents a lua closure * and {@link LuaClosure}, which represents a lua closure
* whose bytecode is interpreted when the function is invoked. * whose bytecode is interpreted when the function is invoked.
* @see LuaValue * @see LuaValue
* @see LuaClosure * @see LuaClosure
* @see org.luaj.vm2.lib.LibFunction * @see org.luaj.vm2.libs.LibFunction
*/ */
abstract abstract
public class LuaFunction extends LuaValue { public class LuaFunction extends LuaValue {

Binary file not shown.

View File

@@ -21,10 +21,10 @@
******************************************************************************/ ******************************************************************************/
package org.luaj.vm2; package org.luaj.vm2;
import org.luaj.vm2.lib.MathLib; import org.luaj.vm2.libs.MathLib;
/** /**
* Extension of {@link LuaNumber} which can hold a Java int as its value. * Extension of {@link LuaNumber} which can hold a Java long as its value.
* <p> * <p>
* These instance are not instantiated directly by clients, but indirectly * These instance are not instantiated directly by clients, but indirectly
* via the static functions {@link LuaValue#valueOf(int)} or {@link LuaValue#valueOf(double)} * via the static functions {@link LuaValue#valueOf(int)} or {@link LuaValue#valueOf(double)}
@@ -59,25 +59,23 @@ public class LuaInteger extends LuaNumber {
* @see LuaValue#valueOf(int) * @see LuaValue#valueOf(int)
* @see LuaValue#valueOf(double) * @see LuaValue#valueOf(double)
*/ */
public static LuaNumber valueOf(long l) { public static LuaInteger valueOf(long l) {
int i = (int) l; int i = (int) l;
return l==i? (i<=255 && i>=-256? intValues[i+256]: return l == i && i <= 255 && i >= -256 ? intValues[i+256] : new LuaInteger(l);
(LuaNumber) new LuaInteger(i)):
(LuaNumber) LuaDouble.valueOf(l);
} }
/** The value being held by this instance. */ /** The value being held by this instance. */
public final int v; public final long v;
/** /**
* Package protected constructor. * Package protected constructor.
* @see LuaValue#valueOf(int) * @see LuaValue#valueOf(int)
**/ **/
LuaInteger(int i) { LuaInteger(long i) {
this.v = i; this.v = i;
} }
public boolean isint() { return true; } public boolean isint() { return v == (int) v; }
public boolean isinttype() { return true; } public boolean isinttype() { return true; }
public boolean islong() { return true; } public boolean islong() { return true; }
@@ -85,33 +83,33 @@ public class LuaInteger extends LuaNumber {
public char tochar() { return (char) v; } public char tochar() { return (char) v; }
public double todouble() { return v; } public double todouble() { return v; }
public float tofloat() { return v; } public float tofloat() { return v; }
public int toint() { return v; } public int toint() { return (int) v; }
public long tolong() { return v; } public long tolong() { return v; }
public short toshort() { return (short) v; } public short toshort() { return (short) v; }
public double optdouble(double defval) { return v; } public double optdouble(double defval) { return v; }
public int optint(int defval) { return v; } public int optint(int defval) { return (int) v; }
public LuaInteger optinteger(LuaInteger defval) { return this; } public LuaInteger optinteger(LuaInteger defval) { return this; }
public long optlong(long defval) { return v; } public long optlong(long defval) { return v; }
public String tojstring() { public String tojstring() {
return Integer.toString(v); return Long.toString(v);
} }
public LuaString strvalue() { public LuaString strvalue() {
return LuaString.valueOf(Integer.toString(v)); return LuaString.valueOf(Long.toString(v));
} }
public LuaString optstring(LuaString defval) { public LuaString optstring(LuaString defval) {
return LuaString.valueOf(Integer.toString(v)); return LuaString.valueOf(Long.toString(v));
} }
public LuaValue tostring() { public LuaValue tostring() {
return LuaString.valueOf(Integer.toString(v)); return LuaString.valueOf(Long.toString(v));
} }
public String optjstring(String defval) { public String optjstring(String defval) {
return Integer.toString(v); return Long.toString(v);
} }
public LuaInteger checkinteger() { public LuaInteger checkinteger() {
@@ -123,15 +121,16 @@ public class LuaInteger extends LuaNumber {
} }
public int hashCode() { public int hashCode() {
return v; return hashCode(v);
} }
public static int hashCode(int x) { public static int hashCode(long x) {
return x; return (int) (x ^ (x >>> 32));
} }
// unary operators // unary operators
public LuaValue neg() { return valueOf(-(long)v); } public LuaValue neg() { return valueOf(-(long)v); }
public LuaValue bnot() { return valueOf(~v); }
// object equality, used for key comparison // object equality, used for key comparison
public boolean equals(Object o) { return o instanceof LuaInteger? ((LuaInteger)o).v == v: false; } public boolean equals(Object o) { return o instanceof LuaInteger? ((LuaInteger)o).v == v: false; }
@@ -144,56 +143,66 @@ public class LuaInteger extends LuaNumber {
public boolean raweq( LuaValue val ) { return val.raweq(v); } public boolean raweq( LuaValue val ) { return val.raweq(v); }
public boolean raweq( double val ) { return v == val; } public boolean raweq( double val ) { return v == val; }
public boolean raweq( int val ) { return v == val; } public boolean raweq( int val ) { return v == val; }
public boolean raweq( long val ) { return v == val; }
// arithmetic operators // arithmetic operators
public LuaValue add( LuaValue rhs ) { return rhs.add(v); } public LuaValue add( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.add(rhs): (n.isinttype()? LuaInteger.valueOf(v + n.tolong()): LuaDouble.valueOf(v + n.todouble())); }
public LuaValue add( double lhs ) { return LuaDouble.valueOf(lhs + v); } public LuaValue add( double lhs ) { return LuaDouble.valueOf(lhs + v); }
public LuaValue add( int lhs ) { return LuaInteger.valueOf(lhs + (long)v); } public LuaValue add( int lhs ) { return LuaInteger.valueOf(lhs + v); }
public LuaValue sub( LuaValue rhs ) { return rhs.subFrom(v); } public LuaValue sub( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.sub(rhs): (n.isinttype()? LuaInteger.valueOf(v - n.tolong()): LuaDouble.valueOf(v - n.todouble())); }
public LuaValue sub( double rhs ) { return LuaDouble.valueOf(v - rhs); } public LuaValue sub( double rhs ) { return LuaDouble.valueOf(v - rhs); }
public LuaValue sub( int rhs ) { return LuaDouble.valueOf(v - rhs); } public LuaValue sub( int rhs ) { return LuaInteger.valueOf(v - rhs); }
public LuaValue subFrom( double lhs ) { return LuaDouble.valueOf(lhs - v); } public LuaValue subFrom( double lhs ) { return LuaDouble.valueOf(lhs - v); }
public LuaValue subFrom( int lhs ) { return LuaInteger.valueOf(lhs - (long)v); } public LuaValue subFrom( int lhs ) { return LuaInteger.valueOf(lhs - v); }
public LuaValue mul( LuaValue rhs ) { return rhs.mul(v); } public LuaValue mul( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.mul(rhs): (n.isinttype()? LuaInteger.valueOf(v * n.tolong()): LuaDouble.valueOf(v * n.todouble())); }
public LuaValue mul( double lhs ) { return LuaDouble.valueOf(lhs * v); } public LuaValue mul( double lhs ) { return LuaDouble.valueOf(lhs * v); }
public LuaValue mul( int lhs ) { return LuaInteger.valueOf(lhs * (long)v); } public LuaValue mul( int lhs ) { return LuaInteger.valueOf(lhs * v); }
public LuaValue pow( LuaValue rhs ) { return rhs.powWith(v); } public LuaValue pow( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.pow(rhs): MathLib.dpow(v, n.todouble()); }
public LuaValue pow( double rhs ) { return MathLib.dpow(v,rhs); } public LuaValue pow( double rhs ) { return MathLib.dpow(v,rhs); }
public LuaValue pow( int rhs ) { return MathLib.dpow(v,rhs); } public LuaValue pow( int rhs ) { return MathLib.dpow(v,rhs); }
public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs,v); } public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs,v); }
public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs,v); } public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs,v); }
public LuaValue div( LuaValue rhs ) { return rhs.divInto(v); } public LuaValue div( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.div(rhs): LuaDouble.ddiv(v, n.todouble()); }
public LuaValue idiv( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.idiv(rhs): (n.isinttype()? LuaInteger.valueOf(luaFloorDiv(v, n.tolong())): LuaDouble.didiv(v, n.todouble())); }
public LuaValue div( double rhs ) { return LuaDouble.ddiv(v,rhs); } public LuaValue div( double rhs ) { return LuaDouble.ddiv(v,rhs); }
public LuaValue div( int rhs ) { return LuaDouble.ddiv(v,rhs); } public LuaValue div( int rhs ) { return LuaDouble.ddiv(v,rhs); }
public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs,v); } public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs,v); }
public LuaValue mod( LuaValue rhs ) { return rhs.modFrom(v); } public LuaValue idiv( double rhs ) { return LuaDouble.didiv(v,rhs); }
public LuaValue idiv( int rhs ) { return LuaInteger.valueOf(luaFloorDiv(v, rhs)); }
public LuaValue idivInto( double lhs ) { return LuaDouble.didiv(lhs,v); }
public LuaValue band( LuaValue rhs ) { LuaValue n = rhs.tonumber(); if (n.isnil()) return super.band(rhs); if (!n.islong()) throw bitwiseError(); return LuaInteger.valueOf(v & n.tolong()); }
public LuaValue bor( LuaValue rhs ) { LuaValue n = rhs.tonumber(); if (n.isnil()) return super.bor(rhs); if (!n.islong()) throw bitwiseError(); return LuaInteger.valueOf(v | n.tolong()); }
public LuaValue bxor( LuaValue rhs ) { LuaValue n = rhs.tonumber(); if (n.isnil()) return super.bxor(rhs); if (!n.islong()) throw bitwiseError(); return LuaInteger.valueOf(v ^ n.tolong()); }
public LuaValue shl( LuaValue rhs ) { LuaValue n = rhs.tonumber(); if (n.isnil()) return super.shl(rhs); if (!n.islong()) throw bitwiseError(); return LuaInteger.valueOf(luaShiftLeft(v, n.tolong())); }
public LuaValue shr( LuaValue rhs ) { LuaValue n = rhs.tonumber(); if (n.isnil()) return super.shr(rhs); if (!n.islong()) throw bitwiseError(); return LuaInteger.valueOf(luaShiftRight(v, n.tolong())); }
public LuaValue mod( LuaValue rhs ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.mod(rhs): (n.isinttype()? LuaInteger.valueOf(luaFloorMod(v, n.tolong())): LuaDouble.dmod(v, n.todouble())); }
public LuaValue mod( double rhs ) { return LuaDouble.dmod(v,rhs); } public LuaValue mod( double rhs ) { return LuaDouble.dmod(v,rhs); }
public LuaValue mod( int rhs ) { return LuaDouble.dmod(v,rhs); } public LuaValue mod( int rhs ) { return LuaInteger.valueOf(luaFloorMod(v, rhs)); }
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 ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.lt(rhs): (n.isinttype()? (v < n.tolong()? TRUE: FALSE): (v < n.todouble()? 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 ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.lt_b(rhs): (n.isinttype()? v < n.tolong(): v < n.todouble()); }
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 ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.lteq(rhs): (n.isinttype()? (v <= n.tolong()? TRUE: FALSE): (v <= n.todouble()? 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 ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.lteq_b(rhs): (n.isinttype()? v <= n.tolong(): v <= n.todouble()); }
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 ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.gt(rhs): (n.isinttype()? (v > n.tolong()? TRUE: FALSE): (v > n.todouble()? 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 ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.gt_b(rhs): (n.isinttype()? v > n.tolong(): v > n.todouble()); }
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 ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.gteq(rhs): (n.isinttype()? (v >= n.tolong()? TRUE: FALSE): (v >= n.todouble()? 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 ) { LuaValue n = rhs.tonumber(); return n.isnil()? super.gteq_b(rhs): (n.isinttype()? v >= n.tolong(): v >= n.todouble()); }
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; }
@@ -201,7 +210,7 @@ public class LuaInteger extends LuaNumber {
public int strcmp( LuaString rhs ) { typerror("attempt to compare number with string"); return 0; } public int strcmp( LuaString rhs ) { typerror("attempt to compare number with string"); return 0; }
public int checkint() { public int checkint() {
return v; return (int) v;
} }
public long checklong() { public long checklong() {
return v; return v;
@@ -216,4 +225,41 @@ public class LuaInteger extends LuaNumber {
return valueOf( String.valueOf(v) ); return valueOf( String.valueOf(v) );
} }
private static long luaFloorDiv(long lhs, long rhs) {
if (rhs == 0) {
throw new LuaError("attempt to divide by zero");
}
long quotient = lhs / rhs;
long remainder = lhs % rhs;
if (remainder != 0 && ((lhs ^ rhs) < 0)) {
quotient--;
}
return quotient;
}
private static long luaFloorMod(long lhs, long rhs) {
if (rhs == 0) {
throw new LuaError("attempt to divide by zero");
}
return lhs - rhs * luaFloorDiv(lhs, rhs);
}
static long luaShiftLeft(long lhs, long rhs) {
if (rhs < 0) {
return luaShiftRight(lhs, -rhs);
}
return rhs >= Long.SIZE ? 0L : lhs << rhs;
}
static long luaShiftRight(long lhs, long rhs) {
if (rhs < 0) {
return luaShiftLeft(lhs, -rhs);
}
return rhs >= Long.SIZE ? 0L : lhs >>> rhs;
}
private static LuaError bitwiseError() {
return new LuaError("number has no integer representation");
}
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -27,8 +27,9 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import org.luaj.vm2.lib.MathLib; import org.luaj.vm2.libs.MathLib;
/** /**
* Subclass of {@link LuaValue} for representing lua strings. * Subclass of {@link LuaValue} for representing lua strings.
@@ -262,6 +263,7 @@ public class LuaString extends LuaValue {
// unary operators // unary operators
public LuaValue neg() { double d = scannumber(); return Double.isNaN(d)? super.neg(): valueOf(-d); } public LuaValue neg() { double d = scannumber(); return Double.isNaN(d)? super.neg(): valueOf(-d); }
public LuaValue bnot() { double d = scannumber(); if (Double.isNaN(d)) return super.bnot(); if (d != (long) d) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(~((long) d)); }
// basic binary arithmetic // basic binary arithmetic
public LuaValue add( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(ADD,rhs): rhs.add(d); } public LuaValue add( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(ADD,rhs): rhs.add(d); }
@@ -280,9 +282,18 @@ public class LuaString extends LuaValue {
public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs, checkarith()); } public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs, checkarith()); }
public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs, checkarith()); } public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs, checkarith()); }
public LuaValue div( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(DIV,rhs): rhs.divInto(d); } public LuaValue div( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(DIV,rhs): rhs.divInto(d); }
public LuaValue idiv( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(IDIV,rhs): rhs.idivInto(d); }
public LuaValue div( double rhs ) { return LuaDouble.ddiv(checkarith(),rhs); } public LuaValue div( double rhs ) { return LuaDouble.ddiv(checkarith(),rhs); }
public LuaValue div( int rhs ) { return LuaDouble.ddiv(checkarith(),rhs); } public LuaValue div( int rhs ) { return LuaDouble.ddiv(checkarith(),rhs); }
public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs, checkarith()); } public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs, checkarith()); }
public LuaValue idiv( double rhs ) { return LuaDouble.didiv(checkarith(),rhs); }
public LuaValue idiv( int rhs ) { return LuaDouble.didiv(checkarith(),rhs); }
public LuaValue idivInto( double lhs ) { return LuaDouble.didiv(lhs, checkarith()); }
public LuaValue band( LuaValue rhs ) { double d = scannumber(); if (Double.isNaN(d)) return super.band(rhs); if (d != (long) d) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.band(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(((long) d) & n.tolong()); }
public LuaValue bor( LuaValue rhs ) { double d = scannumber(); if (Double.isNaN(d)) return super.bor(rhs); if (d != (long) d) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.bor(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(((long) d) | n.tolong()); }
public LuaValue bxor( LuaValue rhs ) { double d = scannumber(); if (Double.isNaN(d)) return super.bxor(rhs); if (d != (long) d) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.bxor(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(((long) d) ^ n.tolong()); }
public LuaValue shl( LuaValue rhs ) { double d = scannumber(); if (Double.isNaN(d)) return super.shl(rhs); if (d != (long) d) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.shl(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(LuaInteger.luaShiftLeft((long) d, n.tolong())); }
public LuaValue shr( LuaValue rhs ) { double d = scannumber(); if (Double.isNaN(d)) return super.shr(rhs); if (d != (long) d) throw new LuaError("number has no integer representation"); LuaValue n = rhs.tonumber(); if (n.isnil()) return super.shr(rhs); if (!n.islong()) throw new LuaError("number has no integer representation"); return LuaInteger.valueOf(LuaInteger.luaShiftRight((long) d, n.tolong())); }
public LuaValue mod( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(MOD,rhs): rhs.modFrom(d); } public LuaValue mod( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(MOD,rhs): rhs.modFrom(d); }
public LuaValue mod( double rhs ) { return LuaDouble.dmod(checkarith(), rhs); } public LuaValue mod( double rhs ) { return LuaDouble.dmod(checkarith(), rhs); }
public LuaValue mod( int rhs ) { return LuaDouble.dmod(checkarith(), rhs); } public LuaValue mod( int rhs ) { return LuaDouble.dmod(checkarith(), rhs); }
@@ -337,13 +348,19 @@ public class LuaString extends LuaValue {
} }
public int checkint() { public int checkint() {
return (int) (long) checkdouble(); return (int) checklong();
} }
public LuaInteger checkinteger() { public LuaInteger checkinteger() {
return valueOf(checkint()); Long value = scanLuaIntegerValue();
if (value == null)
argerror("integer");
return LuaInteger.valueOf(value.longValue());
} }
public long checklong() { public long checklong() {
return (long) checkdouble(); Long value = scanLuaIntegerValue();
if (value == null)
argerror("integer");
return value.longValue();
} }
public double checkdouble() { public double checkdouble() {
double d = scannumber(); double d = scannumber();
@@ -367,19 +384,12 @@ public class LuaString extends LuaValue {
} }
public boolean isint() { public boolean isint() {
double d = scannumber(); Long value = scanLuaIntegerValue();
if ( Double.isNaN(d) ) return value != null && value.intValue() == value.longValue();
return false;
int i = (int) d;
return i == d;
} }
public boolean islong() { public boolean islong() {
double d = scannumber(); return scanLuaIntegerValue() != null;
if ( Double.isNaN(d) )
return false;
long l = (long) d;
return l == d;
} }
public byte tobyte() { return (byte) toint(); } public byte tobyte() { return (byte) toint(); }
@@ -637,21 +647,34 @@ public class LuaString extends LuaValue {
* @see #isValidUtf8() * @see #isValidUtf8()
*/ */
public static String decodeAsUtf8(byte[] bytes, int offset, int length) { public static String decodeAsUtf8(byte[] bytes, int offset, int length) {
int i,j,n,b; int i, j, n;
for (i = offset, j = offset + length, n = 0; i < j; ++n) { for (i = offset, j = offset + length, n = 0; i < j; ++n) {
switch ( 0xE0 & bytes[i++] ) { int b = bytes[i++] & 0xff;
case 0xE0: ++i; if ((b & 0x80) == 0) {
case 0xC0: ++i; continue;
}
if ((b & 0xe0) == 0xc0 && i < j) {
++i;
continue;
}
if ((b & 0xf0) == 0xe0 && i + 1 < j) {
i += 2;
} }
} }
char[] chars = new char[n]; char[] chars = new char[n];
for (i = offset, j = offset + length, n = 0; i < j;) { for (i = offset, j = offset + length, n = 0; i < j;) {
chars[n++] = (char) ( int b = bytes[i++] & 0xff;
((b=bytes[i++])>=0||i>=j)? b: if ((b & 0x80) == 0 || i > j) {
(b<-32||i+1>=j)? (((b&0x3f) << 6) | (bytes[i++]&0x3f)): chars[n++] = (char) b;
(((b&0xf) << 12) | ((bytes[i++]&0x3f)<<6) | (bytes[i++]&0x3f))); } else if ((b & 0xe0) == 0xc0 && i <= j) {
chars[n++] = (char) (((b & 0x1f) << 6) | (bytes[i++] & 0x3f));
} else if ((b & 0xf0) == 0xe0 && i + 1 <= j) {
chars[n++] = (char) (((b & 0x0f) << 12) | ((bytes[i++] & 0x3f) << 6) | (bytes[i++] & 0x3f));
} else {
chars[n++] = (char) b;
} }
return new String(chars); }
return new String(chars, 0, n);
} }
/** /**
@@ -663,12 +686,11 @@ public class LuaString extends LuaValue {
* @see #isValidUtf8() * @see #isValidUtf8()
*/ */
public static int lengthAsUtf8(char[] chars) { public static int lengthAsUtf8(char[] chars) {
int i,b; int n = 0;
char c; for (char c : chars) {
for ( i=b=chars.length; --i>=0; ) n += c < 0x80 ? 1 : c < 0x800 ? 2 : 3;
if ( (c=chars[i]) >=0x80 ) }
b += (c>=0x800)? 2: 1; return n;
return b;
} }
/** /**
@@ -687,21 +709,21 @@ public class LuaString extends LuaValue {
* @see #isValidUtf8() * @see #isValidUtf8()
*/ */
public static int encodeToUtf8(char[] chars, int nchars, byte[] bytes, int off) { public static int encodeToUtf8(char[] chars, int nchars, byte[] bytes, int off) {
char c; int start = off;
int j = off;
for (int i = 0; i < nchars; i++) { for (int i = 0; i < nchars; i++) {
if ( (c = chars[i]) < 0x80 ) { int c = chars[i];
bytes[j++] = (byte) c; if (c < 0x80) {
bytes[off++] = (byte) c;
} else if (c < 0x800) { } else if (c < 0x800) {
bytes[j++] = (byte) (0xC0 | ((c>>6) & 0x1f)); bytes[off++] = (byte) (0xc0 | ((c >> 6) & 0x1f));
bytes[j++] = (byte) (0x80 | ( c & 0x3f)); bytes[off++] = (byte) (0x80 | (c & 0x3f));
} else { } else {
bytes[j++] = (byte) (0xE0 | ((c>>12) & 0x0f)); bytes[off++] = (byte) (0xe0 | ((c >> 12) & 0x0f));
bytes[j++] = (byte) (0x80 | ((c>>6) & 0x3f)); bytes[off++] = (byte) (0x80 | ((c >> 6) & 0x3f));
bytes[j++] = (byte) (0x80 | ( c & 0x3f)); bytes[off++] = (byte) (0x80 | (c & 0x3f));
} }
} }
return j - off; return off - start;
} }
/** Check that a byte sequence is valid UTF-8 /** Check that a byte sequence is valid UTF-8
@@ -735,8 +757,7 @@ public class LuaString extends LuaValue {
* @see LuaValue#tonumber() * @see LuaValue#tonumber()
*/ */
public LuaValue tonumber() { public LuaValue tonumber() {
double d = scannumber(); return scanLuaNumberValue();
return Double.isNaN(d)? NIL: valueOf(d);
} }
/** /**
@@ -747,7 +768,11 @@ public class LuaString extends LuaValue {
*/ */
public LuaValue tonumber( int base ) { public LuaValue tonumber( int base ) {
double d = scannumber( base ); double d = scannumber( base );
return Double.isNaN(d)? NIL: valueOf(d); if (Double.isNaN(d)) {
return NIL;
}
long l = (long) d;
return l == d ? LuaInteger.valueOf(l) : valueOf(d);
} }
/** /**
@@ -761,12 +786,56 @@ public class LuaString extends LuaValue {
while ( i<j && m_bytes[j-1]==' ' ) --j; while ( i<j && m_bytes[j-1]==' ' ) --j;
if ( i>=j ) if ( i>=j )
return Double.NaN; return Double.NaN;
if ( m_bytes[i]=='0' && i+1<j && (m_bytes[i+1]=='x'||m_bytes[i+1]=='X')) int prefix = (m_bytes[i] == '+' || m_bytes[i] == '-') ? i + 1 : i;
return scanlong(16, i+2, j); if (prefix + 1 < j && m_bytes[prefix]=='0' && (m_bytes[prefix+1]=='x'||m_bytes[prefix+1]=='X')) {
double l = scanlong(16, prefix + 2, j, i != prefix);
return Double.isNaN(l)? scandouble(i,j): l;
}
double l = scanlong(10, i, j); double l = scanlong(10, i, j);
return Double.isNaN(l)? scandouble(i,j): l; return Double.isNaN(l)? scandouble(i,j): l;
} }
private LuaValue scanLuaNumberValue() {
int i = m_offset, j = m_offset + m_length;
while (i < j && m_bytes[i] == ' ') ++i;
while (i < j && m_bytes[j - 1] == ' ') --j;
if (i >= j) {
return NIL;
}
int prefix = (m_bytes[i] == '+' || m_bytes[i] == '-') ? i + 1 : i;
if (prefix + 1 < j && m_bytes[prefix] == '0' && (m_bytes[prefix + 1] == 'x' || m_bytes[prefix + 1] == 'X')) {
try {
String s = new String(m_bytes, i, j - i, java.nio.charset.StandardCharsets.ISO_8859_1);
if (s.indexOf('.') >= 0 || s.indexOf('p') >= 0 || s.indexOf('P') >= 0) {
return valueOf(Double.parseDouble(s));
}
String digits = s.startsWith("+") || s.startsWith("-") ? s.substring(3) : s.substring(2);
long value = Long.parseUnsignedLong(digits, 16);
if (s.startsWith("-")) {
if (value == Long.MIN_VALUE) {
return LuaInteger.valueOf(Long.MIN_VALUE);
}
return LuaInteger.valueOf(-value);
}
return LuaInteger.valueOf(value);
} catch (NumberFormatException e) {
return NIL;
}
}
double l = scanlong(10, i, j);
if (!Double.isNaN(l)) {
long lv = (long) l;
return lv == l ? LuaInteger.valueOf(lv) : valueOf(l);
}
double d = scandouble(i, j);
return Double.isNaN(d) ? NIL : valueOf(d);
}
private Long scanLuaIntegerValue() {
LuaValue value = scanLuaNumberValue();
return value.islong() ? Long.valueOf(value.tolong()) : null;
}
/** /**
* Convert to a number in a base, or return Double.NaN if not a number. * Convert to a number in a base, or return Double.NaN if not a number.
* @param base the base to use between 2 and 36 * @param base the base to use between 2 and 36
@@ -792,9 +861,15 @@ public class LuaString extends LuaValue {
* or Double.NaN if not * or Double.NaN if not
*/ */
private double scanlong( int base, int start, int end ) { private double scanlong( int base, int start, int end ) {
return scanlong(base, start, end, false);
}
private double scanlong( int base, int start, int end, boolean hasSign ) {
long x = 0; long x = 0;
boolean neg = (m_bytes[start] == '-'); boolean neg = hasSign && m_bytes[start - 1] == '-';
for ( int i=(neg?start+1:start); i<end; i++ ) { if (start >= end)
return Double.NaN;
for ( int i=start; i<end; i++ ) {
int digit = m_bytes[i] - (base<=10||(m_bytes[i]>='0'&&m_bytes[i]<='9')? '0': int digit = m_bytes[i] - (base<=10||(m_bytes[i]>='0'&&m_bytes[i]<='9')? '0':
m_bytes[i]>='A'&&m_bytes[i]<='Z'? ('A'-10): ('a'-10)); m_bytes[i]>='A'&&m_bytes[i]<='Z'? ('A'-10): ('a'-10));
if ( digit < 0 || digit >= base ) if ( digit < 0 || digit >= base )
@@ -821,8 +896,12 @@ public class LuaString extends LuaValue {
case '+': case '+':
case '.': case '.':
case 'e': case 'E': case 'e': case 'E':
case 'p': case 'P':
case 'x': case 'X':
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
case 'a': case 'b': case 'c': case 'd': case 'f':
case 'A': case 'B': case 'C': case 'D': case 'F':
break; break;
default: default:
return Double.NaN; return Double.NaN;

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -472,8 +472,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) )
@@ -719,7 +718,9 @@ public class LuaTable extends LuaValue implements Metatable {
if ( ( k = slot.arraykey( newArraySize ) ) > 0 ) { if ( ( k = slot.arraykey( newArraySize ) ) > 0 ) {
StrongSlot entry = slot.first(); StrongSlot entry = slot.first();
if (entry != null) if (entry != null)
newArray[ k - 1 ] = entry.value(); newArray[ k - 1 ] = m_metatable != null
? m_metatable.wrap(entry.value())
: entry.value();
} else if ( !(slot instanceof DeadSlot) ) { } else if ( !(slot instanceof DeadSlot) ) {
int j = slot.keyindex( newHashMask ); int j = slot.keyindex( newHashMask );
newHash[j] = slot.relink( newHash[j] ); newHash[j] = slot.relink( newHash[j] );
@@ -769,7 +770,7 @@ public class LuaTable extends LuaValue implements Metatable {
protected static Entry defaultEntry(LuaValue key, LuaValue value) { protected static Entry defaultEntry(LuaValue key, LuaValue value) {
if ( key.isinttype() ) { if ( key.isinttype() ) {
return new IntKeyEntry( key.toint(), value ); return new IntKeyEntry( key.toint(), value );
} else if (value.type() == TNUMBER) { } else if (value.type() == TNUMBER && !value.isinttype()) {
return new NumberValueEntry( key, value.todouble() ); return new NumberValueEntry( key, value.todouble() );
} else { } else {
return new NormalEntry( key, value ); return new NormalEntry( key, value );

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,335 @@
/*******************************************************************************
* Copyright (c) 2007-2012 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.
******************************************************************************/
package org.luaj.vm2;
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
* a lua coroutine thread using Java Threads.
* <p>
* A LuaThread is typically created in response to a scripted call to
* {@code coroutine.create()}
* <p>
* The threads must be initialized with the globals, so that
* the global environment may be passed along according to rules of lua.
* This is done via the constructor arguments {@link #LuaThread(Globals)} or
* {@link #LuaThread(Globals, LuaValue)}.
* <p>
* The utility classes {@link org.luaj.vm2.libs.jse.JsePlatform} and
* {@link org.luaj.vm2.libs.jme.JmePlatform}
* see to it that this {@link Globals} are initialized properly.
* <p>
* The behavior of coroutine threads matches closely the behavior
* of C coroutine library. However, because of the use of Java threads
* to manage call state, it is possible to yield from anywhere in luaj.
* <p>
* Each Java thread wakes up at regular intervals and checks a weak reference
* to determine if it can ever be resumed. If not, it throws
* {@link OrphanedThread} which is an {@link java.lang.Error}.
* Applications should not catch {@link OrphanedThread}, because it can break
* the thread safety of luaj. The value controlling the polling interval
* is {@link #thread_orphan_check_interval} and may be set by the user.
* <p>
* There are two main ways to abandon a coroutine. The first is to call
* {@code yield()} from lua, or equivalently {@link Globals#yield(Varargs)},
* and arrange to have it never resumed possibly by values passed to yield.
* The second is to throw {@link OrphanedThread}, which should put the thread
* in a dead state. In either case all references to the thread must be
* dropped, and the garbage collector must run for the thread to be
* garbage collected.
*
*
* @see LuaValue
* @see org.luaj.vm2.libs.jse.JsePlatform
* @see org.luaj.vm2.libs.jme.JmePlatform
* @see org.luaj.vm2.libs.CoroutineLib
*/
public class LuaThread extends LuaValue {
/** Shared metatable for lua threads. */
public static LuaValue s_metatable;
/** The current number of coroutines. Should not be set. */
public static int coroutine_count = 0;
/** Polling interval, in milliseconds, which each thread uses while waiting to
* return from a yielded state to check if the lua threads is no longer
* referenced and therefore should be garbage collected.
* A short polling interval for many threads will consume server resources.
* Orphaned threads cannot be detected and collected unless garbage
* collection is run. This can be changed by Java startup code if desired.
*/
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_SUSPENDED = 1;
public static final int STATUS_RUNNING = 2;
public static final int STATUS_NORMAL = 3;
public static final int STATUS_DEAD = 4;
public static final String[] STATUS_NAMES = {
"suspended",
"suspended",
"running",
"normal",
"dead",};
public final State state;
public static final int MAX_CALLSTACK = 256;
/** Thread-local used by DebugLib to store debugging state.
* This is an opaque value that should not be modified by applications. */
public Object callstack;
public final Globals globals;
/** Error message handler for this thread, if any. */
public LuaValue errorfunc;
/** Private constructor for main thread only */
public LuaThread(Globals globals) {
state = new State(globals, this, null);
state.status = STATUS_RUNNING;
this.globals = globals;
}
/**
* Create a LuaThread around a function and environment
* @param func The function to execute
*/
public LuaThread(Globals globals, LuaValue func) {
LuaValue.assert_(func != null, "function cannot be null");
state = new State(globals, this, func);
this.globals = globals;
}
public int type() {
return LuaValue.TTHREAD;
}
public String typename() {
return "thread";
}
public boolean isthread() {
return true;
}
public LuaThread optthread(LuaThread defval) {
return this;
}
public LuaThread checkthread() {
return this;
}
public LuaValue getmetatable() {
return s_metatable;
}
public String getStatus() {
return STATUS_NAMES[state.status];
}
public boolean isMainThread() {
return this.state.function == null;
}
public Varargs resume(Varargs args) {
final LuaThread.State s = this.state;
if (s.status > LuaThread.STATUS_SUSPENDED)
return LuaValue.varargsOf(LuaValue.FALSE,
LuaValue.valueOf("cannot resume "+(s.status==LuaThread.STATUS_DEAD? "dead": "non-suspended")+" coroutine"));
return s.lua_resume(this, args);
}
public Varargs close() {
if (isMainThread())
return LuaValue.varargsOf(LuaValue.FALSE, LuaValue.valueOf("cannot close main thread"));
return state.lua_close();
}
public static class State implements Runnable {
private final Globals globals;
final WeakReference lua_thread;
public final LuaValue function;
Varargs args = LuaValue.NONE;
Varargs result = LuaValue.NONE;
String error = null;
/** Hook function control state used by debug lib. */
public LuaValue hookfunc;
public boolean hookline;
public boolean hookcall;
public boolean hookrtrn;
public int hookcount;
public boolean inhook;
public int lastline;
public int bytecodes;
public int status = LuaThread.STATUS_INITIAL;
private Lock locker = new ReentrantLock();
private Condition cond = locker.newCondition();
private Thread thread;
State(Globals globals, LuaThread lua_thread, LuaValue function) {
this.globals = globals;
this.lua_thread = new WeakReference(lua_thread);
this.function = function;
}
public void run() {
locker.lock();
try {
try {
Varargs a = this.args;
this.args = LuaValue.NONE;
this.result = function.invoke(a);
} catch (Throwable t) {
this.error = t.getMessage();
} finally {
this.status = LuaThread.STATUS_DEAD;
cond.signal();
}
} finally {
locker.unlock();
}
}
public Varargs lua_resume(LuaThread new_thread, Varargs args) {
locker.lock();
try {
LuaThread previous_thread = globals.running;
try {
globals.running = new_thread;
this.args = args;
if (this.status == STATUS_INITIAL) {
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){
t = new Thread(this, "Coroutine-"+(++coroutine_count));
t.start();
}
this.thread = t;
} else {
cond.signal();
}
if (previous_thread != null)
previous_thread.state.status = STATUS_NORMAL;
this.status = STATUS_RUNNING;
cond.await();
return (this.error != null?
LuaValue.varargsOf(LuaValue.FALSE, LuaValue.valueOf(this.error)):
LuaValue.varargsOf(LuaValue.TRUE, this.result));
} catch (InterruptedException ie) {
throw new OrphanedThread();
} finally {
this.args = LuaValue.NONE;
this.result = LuaValue.NONE;
this.error = null;
globals.running = previous_thread;
if (previous_thread != null)
globals.running.state.status =STATUS_RUNNING;
}
} finally {
locker.unlock();
}
}
public Varargs lua_yield(Varargs args) {
locker.lock();
try {
try {
this.result = args;
this.status = STATUS_SUSPENDED;
cond.signal();
do {
cond.await(thread_orphan_check_interval,TimeUnit.MILLISECONDS);
if (this.lua_thread.get() == null) {
this.status = STATUS_DEAD;
throw new OrphanedThread();
}
} while (this.status == STATUS_SUSPENDED);
return this.args;
} catch (InterruptedException ie) {
this.status = STATUS_DEAD;
throw new OrphanedThread();
} finally {
this.args = LuaValue.NONE;
this.result = LuaValue.NONE;
}
} finally {
locker.unlock();
}
}
public Varargs lua_close() {
locker.lock();
try {
if (status == STATUS_DEAD)
return LuaValue.TRUE;
if (status == STATUS_RUNNING || status == STATUS_NORMAL)
return LuaValue.varargsOf(LuaValue.FALSE, LuaValue.valueOf("cannot close running coroutine"));
status = STATUS_DEAD;
if (thread != null)
thread.interrupt();
cond.signalAll();
return LuaValue.TRUE;
} finally {
locker.unlock();
}
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -75,7 +75,7 @@ package org.luaj.vm2;
* } </pre> * } </pre>
* For this to work the file must be in the current directory, or in the class path, * For this to work the file must be in the current directory, or in the class path,
* dependening on the platform. * dependening on the platform.
* See {@link org.luaj.vm2.lib.jse.JsePlatform} and {@link org.luaj.vm2.lib.jme.JmePlatform} for details. * See {@link org.luaj.vm2.libs.jse.JsePlatform} and {@link org.luaj.vm2.libs.jme.JmePlatform} for details.
* <p> * <p>
* In general a {@link LuaError} may be thrown on any operation when the * In general a {@link LuaError} may be thrown on any operation when the
* types supplied to any operation are illegal from a lua perspective. * types supplied to any operation are illegal from a lua perspective.
@@ -99,10 +99,10 @@ package org.luaj.vm2;
* {@link #INDEX}, {@link #NEWINDEX}, {@link #CALL}, {@link #MODE}, {@link #METATABLE}, * {@link #INDEX}, {@link #NEWINDEX}, {@link #CALL}, {@link #MODE}, {@link #METATABLE},
* {@link #ADD}, {@link #SUB}, {@link #DIV}, {@link #MUL}, {@link #POW}, * {@link #ADD}, {@link #SUB}, {@link #DIV}, {@link #MUL}, {@link #POW},
* {@link #MOD}, {@link #UNM}, {@link #LEN}, {@link #EQ}, {@link #LT}, * {@link #MOD}, {@link #UNM}, {@link #LEN}, {@link #EQ}, {@link #LT},
* {@link #LE}, {@link #TOSTRING}, and {@link #CONCAT}. * {@link #LE}, {@link #TOSTRING}, {@link #CONCAT}, {@link #PAIRS}, and {@link #IPAIRS}.
* *
* @see org.luaj.vm2.lib.jse.JsePlatform * @see org.luaj.vm2.libs.jse.JsePlatform
* @see org.luaj.vm2.lib.jme.JmePlatform * @see org.luaj.vm2.libs.jme.JmePlatform
* @see LoadState * @see LoadState
* @see Varargs * @see Varargs
*/ */
@@ -213,6 +213,27 @@ public class LuaValue extends Varargs {
/** LuaString constant with value "__div" for use as metatag */ /** LuaString constant with value "__div" for use as metatag */
public static final LuaString DIV = valueOf("__div"); public static final LuaString DIV = valueOf("__div");
/** LuaString constant with value "__idiv" for use as metatag */
public static final LuaString IDIV = valueOf("__idiv");
/** LuaString constant with value "__band" for use as metatag */
public static final LuaString BAND = valueOf("__band");
/** LuaString constant with value "__bor" for use as metatag */
public static final LuaString BOR = valueOf("__bor");
/** LuaString constant with value "__bxor" for use as metatag */
public static final LuaString BXOR = valueOf("__bxor");
/** LuaString constant with value "__shl" for use as metatag */
public static final LuaString SHL = valueOf("__shl");
/** LuaString constant with value "__shr" for use as metatag */
public static final LuaString SHR = valueOf("__shr");
/** LuaString constant with value "__bnot" for use as metatag */
public static final LuaString BNOT = valueOf("__bnot");
/** LuaString constant with value "__mul" for use as metatag */ /** LuaString constant with value "__mul" for use as metatag */
public static final LuaString MUL = valueOf("__mul"); public static final LuaString MUL = valueOf("__mul");
@@ -243,6 +264,15 @@ public class LuaValue extends Varargs {
/** LuaString constant with value "__concat" for use as metatag */ /** LuaString constant with value "__concat" for use as metatag */
public static final LuaString CONCAT = valueOf("__concat"); public static final LuaString CONCAT = valueOf("__concat");
/** LuaString constant with value "__pairs" for use as metatag */
public static final LuaString PAIRS = valueOf("__pairs");
/** LuaString constant with value "__ipairs" for use as metatag */
public static final LuaString IPAIRS = valueOf("__ipairs");
/** LuaString constant with value "__close" for use as metatag */
public static final LuaString CLOSE = valueOf("__close");
/** LuaString constant with value "" */ /** LuaString constant with value "" */
public static final LuaString EMPTYSTRING = valueOf(""); public static final LuaString EMPTYSTRING = valueOf("");
@@ -2008,6 +2038,13 @@ public class LuaValue extends Varargs {
*/ */
public LuaValue neg() { return checkmetatag(UNM, "attempt to perform arithmetic on ").call(this); } public LuaValue neg() { return checkmetatag(UNM, "attempt to perform arithmetic on ").call(this); }
/** Unary bitwise not: return bitwise inverse value {@code (~this)}.
* @return numeric inverse as {@link LuaNumber} if integer-coercible,
* or metatag processing result if {@link #BNOT} metatag is defined
* @throws LuaError if {@code this} cannot be represented as an integer
*/
public LuaValue bnot() { return checkmetatag(BNOT, "attempt to perform bitwise operation on ").call(this); }
/** Length operator: return lua length of object {@code (#this)} including metatag processing as java int /** Length operator: return lua length of object {@code (#this)} including metatag processing as java int
* @return length as defined by the lua # operator * @return length as defined by the lua # operator
* or metatag processing result * or metatag processing result
@@ -2138,6 +2175,15 @@ public class LuaValue extends Varargs {
*/ */
public boolean raweq( int val ) { return false; } public boolean raweq( int val ) { return false; }
/** Equals: Perform direct equality comparison with a long value
* without metatag processing.
* @param val The long value to compare with.
* @return true if {@code this} is a {@link LuaNumber}
* whose value equals val,
* otherwise false
*/
public boolean raweq( long val ) { return false; }
/** Perform equality testing metatag processing /** Perform equality testing metatag processing
* @param lhs left-hand-side of equality expression * @param lhs left-hand-side of equality expression
* @param lhsmt metatag value for left-hand-side * @param lhsmt metatag value for left-hand-side
@@ -2399,6 +2445,18 @@ public class LuaValue extends Varargs {
*/ */
public LuaValue div( LuaValue rhs ) { return arithmt(DIV,rhs); } public LuaValue div( LuaValue rhs ) { return arithmt(DIV,rhs); }
public LuaValue idiv( LuaValue rhs ) { return arithmt(IDIV,rhs); }
public LuaValue band( LuaValue rhs ) { return arithmt(BAND,rhs); }
public LuaValue bor( LuaValue rhs ) { return arithmt(BOR,rhs); }
public LuaValue bxor( LuaValue rhs ) { return arithmt(BXOR,rhs); }
public LuaValue shl( LuaValue rhs ) { return arithmt(SHL,rhs); }
public LuaValue shr( LuaValue rhs ) { return arithmt(SHR,rhs); }
/** Divide: Perform numeric divide operation by another value /** Divide: Perform numeric divide operation by another value
* of double type without metatag processing * of double type without metatag processing
* <p> * <p>
@@ -2414,6 +2472,18 @@ public class LuaValue extends Varargs {
*/ */
public LuaValue div( double rhs ) { return aritherror("div"); } public LuaValue div( double rhs ) { return aritherror("div"); }
public LuaValue idiv( double rhs ) { return aritherror("idiv"); }
public LuaValue band( double rhs ) { return aritherror("band"); }
public LuaValue bor( double rhs ) { return aritherror("bor"); }
public LuaValue bxor( double rhs ) { return aritherror("bxor"); }
public LuaValue shl( double rhs ) { return aritherror("shl"); }
public LuaValue shr( double rhs ) { return aritherror("shr"); }
/** Divide: Perform numeric divide operation by another value /** Divide: Perform numeric divide operation by another value
* of int type without metatag processing * of int type without metatag processing
* <p> * <p>
@@ -2429,6 +2499,18 @@ public class LuaValue extends Varargs {
*/ */
public LuaValue div( int rhs ) { return aritherror("div"); } public LuaValue div( int rhs ) { return aritherror("div"); }
public LuaValue idiv( int rhs ) { return aritherror("idiv"); }
public LuaValue band( int rhs ) { return aritherror("band"); }
public LuaValue bor( int rhs ) { return aritherror("bor"); }
public LuaValue bxor( int rhs ) { return aritherror("bxor"); }
public LuaValue shl( int rhs ) { return aritherror("shl"); }
public LuaValue shr( int rhs ) { return aritherror("shr"); }
/** Reverse-divide: Perform numeric divide operation into another value /** Reverse-divide: Perform numeric divide operation into another value
* with metatag processing * with metatag processing
* <p> * <p>
@@ -2444,6 +2526,18 @@ public class LuaValue extends Varargs {
*/ */
public LuaValue divInto(double lhs) { return arithmtwith(DIV,lhs); } public LuaValue divInto(double lhs) { return arithmtwith(DIV,lhs); }
public LuaValue idivInto(double lhs) { return arithmtwith(IDIV,lhs); }
public LuaValue bandInto(double lhs) { return arithmtwith(BAND,lhs); }
public LuaValue borInto(double lhs) { return arithmtwith(BOR,lhs); }
public LuaValue bxorInto(double lhs) { return arithmtwith(BXOR,lhs); }
public LuaValue shlInto(double lhs) { return arithmtwith(SHL,lhs); }
public LuaValue shrInto(double lhs) { return arithmtwith(SHR,lhs); }
/** Modulo: Perform numeric modulo operation with another value /** Modulo: Perform numeric modulo operation with another value
* of unknown type, * of unknown type,
* including metatag processing. * including metatag processing.
@@ -3163,6 +3257,13 @@ public class LuaValue extends Varargs {
*/ */
public static LuaInteger valueOf(int i) { return LuaInteger.valueOf(i); } public static LuaInteger valueOf(int i) { return LuaInteger.valueOf(i); }
/** Convert java long to a {@link LuaValue}.
*
* @param l long value to convert
* @return {@link LuaInteger} instance, possibly pooled, whose value is l
*/
public static LuaInteger valueOf(long l) { return LuaInteger.valueOf(l); }
/** Convert java double to a {@link LuaValue}. /** Convert java double to a {@link LuaValue}.
* This may return a {@link LuaInteger} or {@link LuaDouble} depending * This may return a {@link LuaInteger} or {@link LuaDouble} depending
* on the value supplied. * on the value supplied.
@@ -3402,8 +3503,8 @@ public class LuaValue extends Varargs {
switch ( v.length ) { switch ( v.length ) {
case 0: return NONE; case 0: return NONE;
case 1: return v[0]; case 1: return v[0];
case 2: return new Varargs.PairVarargs(v[0],v[1]); case 2: return new PairVarargs(v[0],v[1]);
default: return new Varargs.ArrayVarargs(v,NONE); default: return new ArrayVarargs(v,NONE);
} }
} }
@@ -3419,12 +3520,12 @@ public class LuaValue extends Varargs {
switch ( v.length ) { switch ( v.length ) {
case 0: return r; case 0: return r;
case 1: return r.narg()>0? case 1: return r.narg()>0?
(Varargs) new Varargs.PairVarargs(v[0],r): (Varargs) new PairVarargs(v[0],r):
(Varargs) v[0]; (Varargs) v[0];
case 2: return r.narg()>0? case 2: return r.narg()>0?
(Varargs) new Varargs.ArrayVarargs(v,r): (Varargs) new ArrayVarargs(v,r):
(Varargs) new Varargs.PairVarargs(v[0],v[1]); (Varargs) new PairVarargs(v[0],v[1]);
default: return new Varargs.ArrayVarargs(v,r); default: return new ArrayVarargs(v,r);
} }
} }
@@ -3441,8 +3542,8 @@ public class LuaValue extends Varargs {
switch ( length ) { switch ( length ) {
case 0: return NONE; case 0: return NONE;
case 1: return v[offset]; case 1: return v[offset];
case 2: return new Varargs.PairVarargs(v[offset+0],v[offset+1]); case 2: return new PairVarargs(v[offset+0],v[offset+1]);
default: return new Varargs.ArrayPartVarargs(v, offset, length, NONE); default: return new ArrayPartVarargs(v, offset, length, NONE);
} }
} }
@@ -3463,12 +3564,12 @@ public class LuaValue extends Varargs {
switch ( length ) { switch ( length ) {
case 0: return more; case 0: return more;
case 1: return more.narg()>0? case 1: return more.narg()>0?
(Varargs) new Varargs.PairVarargs(v[offset],more): (Varargs) new PairVarargs(v[offset],more):
(Varargs) v[offset]; (Varargs) v[offset];
case 2: return more.narg()>0? case 2: return more.narg()>0?
(Varargs) new Varargs.ArrayPartVarargs(v,offset,length,more): (Varargs) new ArrayPartVarargs(v,offset,length,more):
(Varargs) new Varargs.PairVarargs(v[offset],v[offset+1]); (Varargs) new PairVarargs(v[offset],v[offset+1]);
default: return new Varargs.ArrayPartVarargs(v,offset,length,more); default: return new ArrayPartVarargs(v,offset,length,more);
} }
} }
@@ -3485,7 +3586,7 @@ public class LuaValue extends Varargs {
public static Varargs varargsOf(LuaValue v, Varargs r) { public static Varargs varargsOf(LuaValue v, Varargs r) {
switch ( r.narg() ) { switch ( r.narg() ) {
case 0: return v; case 0: return v;
default: return new Varargs.PairVarargs(v,r); default: return new PairVarargs(v,r);
} }
} }
@@ -3502,8 +3603,8 @@ public class LuaValue extends Varargs {
*/ */
public static Varargs varargsOf(LuaValue v1,LuaValue v2,Varargs v3) { public static Varargs varargsOf(LuaValue v1,LuaValue v2,Varargs v3) {
switch ( v3.narg() ) { switch ( v3.narg() ) {
case 0: return new Varargs.PairVarargs(v1,v2); case 0: return new PairVarargs(v1,v2);
default: return new Varargs.ArrayPartVarargs(new LuaValue[]{v1,v2}, 0, 2, v3); default: return new ArrayPartVarargs(new LuaValue[]{v1,v2}, 0, 2, v3);
} }
} }

Binary file not shown.

Binary file not shown.

View File

@@ -22,7 +22,7 @@
package org.luaj.vm2; package org.luaj.vm2;
/** /**
* {@link java.lang.Error} sublcass that indicates a lua thread that is no * {@link Error} sublcass that indicates a lua thread that is no
* longer referenced has been detected. * longer referenced has been detected.
* <p> * <p>
* The java thread in which this is thrown should correspond to a * The java thread in which this is thrown should correspond to a

Binary file not shown.

View File

@@ -276,6 +276,12 @@ public class Print extends Lua {
case OP_SUB: case OP_SUB:
case OP_MUL: case OP_MUL:
case OP_DIV: case OP_DIV:
case OP_IDIV:
case OP_BAND:
case OP_BOR:
case OP_BXOR:
case OP_SHL:
case OP_SHR:
case OP_POW: case OP_POW:
case OP_EQ: case OP_EQ:
case OP_LT: case OP_LT:

Binary file not shown.

View File

@@ -99,6 +99,7 @@ public class Prototype {
public int lastlinedefined; public int lastlinedefined;
public int numparams; public int numparams;
public int is_vararg; public int is_vararg;
public LuaString varargname;
public int maxstacksize; public int maxstacksize;
private static final Upvaldesc[] NOUPVALUES = {}; private static final Upvaldesc[] NOUPVALUES = {};
private static final Prototype[] NOSUBPROTOS = {}; private static final Prototype[] NOSUBPROTOS = {};

View File

@@ -0,0 +1,5 @@
package org.luaj.vm2;
public interface PrototypeProvider {
Prototype prototype();
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -32,10 +32,18 @@ public class Upvaldesc {
/* index of upvalue (in stack or in outer function's list) */ /* index of upvalue (in stack or in outer function's list) */
public final short idx; public final short idx;
/* whether assignments to this upvalue are forbidden by a <const> local */
public final boolean isconst;
public Upvaldesc(LuaString name, boolean instack, int idx) { public Upvaldesc(LuaString name, boolean instack, int idx) {
this(name, instack, idx, false);
}
public Upvaldesc(LuaString name, boolean instack, int idx, boolean isconst) {
this.name = name; this.name = name;
this.instack = instack; this.instack = instack;
this.idx = (short) idx; this.idx = (short) idx;
this.isconst = isconst;
} }
public String toString() { public String toString() {

Binary file not shown.

View File

@@ -537,7 +537,7 @@ public abstract class Varargs {
if (newstart == this.end) if (newstart == this.end)
return v.arg(this.end); return v.arg(this.end);
if (newstart == this.end-1) if (newstart == this.end-1)
return new Varargs.PairVarargs(v.arg(this.end-1), v.arg(this.end)); return new PairVarargs(v.arg(this.end-1), v.arg(this.end));
return new SubVarargs(v, newstart, this.end); return new SubVarargs(v, newstart, this.end);
} }
return new SubVarargs(v, newstart, this.end); return new SubVarargs(v, newstart, this.end);

Some files were not shown because too many files have changed in this diff Show More