Supply environment as extra argument when loading functions.
This commit is contained in:
130
README.html
130
README.html
@@ -16,7 +16,7 @@
|
||||
Getting Started with LuaJ
|
||||
|
||||
</h1>
|
||||
James Roseborough, Ian Farmer, Version 3.0-alpha1
|
||||
James Roseborough, Ian Farmer, Version 3.0-alpha2
|
||||
<p>
|
||||
<small>
|
||||
Copyright © 2009-2012 Luaj.org.
|
||||
@@ -117,7 +117,7 @@ in comparison with the standard C distribution.
|
||||
<td>16.794</td>
|
||||
<td>11.274</td>
|
||||
<td>Java</td>
|
||||
<td>java -cp luaj-jse-3.0-alpha1.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr>
|
||||
<td>java -cp luaj-jse-3.0-alpha2.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr>
|
||||
<tr valign="top">
|
||||
<td></td>
|
||||
<td></td>
|
||||
@@ -127,7 +127,7 @@ in comparison with the standard C distribution.
|
||||
<td>36.894</td>
|
||||
<td>15.163</td>
|
||||
<td></td>
|
||||
<td>java -cp luaj-jse-3.0-alpha1.jar lua -n fannkuch.lua 10</td></tr>
|
||||
<td>java -cp luaj-jse-3.0-alpha2.jar lua -n fannkuch.lua 10</td></tr>
|
||||
<tr valign="top">
|
||||
<td>lua</td>
|
||||
<td>5.1.4</td>
|
||||
@@ -183,7 +183,7 @@ It is also faster than Java-lua implementations Jill, Kahlua, and Mochalua for a
|
||||
From the main distribution directory line type:
|
||||
|
||||
<pre>
|
||||
java -cp lib/luaj-jse-3.0-alpha1.jar lua examples/lua/hello.lua
|
||||
java -cp lib/luaj-jse-3.0-alpha2.jar lua examples/lua/hello.lua
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -195,7 +195,7 @@ You should see the following output:
|
||||
To see how luaj can be used to acccess most Java API's including swing, try:
|
||||
|
||||
<pre>
|
||||
java -cp lib/luaj-jse-3.0-alpha1.jar lua examples/lua/swingapp.lua
|
||||
java -cp lib/luaj-jse-3.0-alpha2.jar lua examples/lua/swingapp.lua
|
||||
</pre>
|
||||
|
||||
<h2>Compile lua source to lua bytecode</h2>
|
||||
@@ -204,8 +204,8 @@ To see how luaj can be used to acccess most Java API's including swing, try:
|
||||
From the main distribution directory line type:
|
||||
|
||||
<pre>
|
||||
java -cp lib/luaj-jse-3.0-alpha1.jar luac examples/lua/hello.lua
|
||||
java -cp lib/luaj-jse-3.0-alpha1.jar lua luac.out
|
||||
java -cp lib/luaj-jse-3.0-alpha2.jar luac examples/lua/hello.lua
|
||||
java -cp lib/luaj-jse-3.0-alpha2.jar lua luac.out
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -219,8 +219,8 @@ Luaj can compile lua sources or binaries directly to java bytecode if the bcel l
|
||||
|
||||
<pre>
|
||||
ant bcel-lib
|
||||
java -cp "lib/luaj-jse-3.0-alpha1.jar;lib/bcel-5.2.jar" luajc -s examples/lua -d . hello.lua
|
||||
java -cp "lib/luaj-jse-3.0-alpha1.jar;." lua -l hello
|
||||
java -cp "lib/luaj-jse-3.0-alpha2.jar;lib/bcel-5.2.jar" luajc -s examples/lua -d . hello.lua
|
||||
java -cp "lib/luaj-jse-3.0-alpha2.jar;." lua -l hello
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -231,7 +231,7 @@ but the compiled classes must be in the class path at runtime, unless runtime ji
|
||||
<p>
|
||||
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-b</em></b> option and providing the <em>bcel</em> library in the class path:
|
||||
<pre>
|
||||
java -cp "lib/luaj-jse-3.0-alpha1.jar;lib/bcel-5.2.jar" lua -b examples/lua/hello.lua
|
||||
java -cp "lib/luaj-jse-3.0-alpha2.jar;lib/bcel-5.2.jar" lua -b examples/lua/hello.lua
|
||||
</pre>
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ A simple example may be found in
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
You must include the library <b>lib/luaj-jse-3.0-alpha1.jar</b> in your class path.
|
||||
You must include the library <b>lib/luaj-jse-3.0-alpha2.jar</b> in your class path.
|
||||
|
||||
<h2>Run a script in a MIDlet</h2>
|
||||
|
||||
@@ -283,7 +283,7 @@ A simple example may be found in
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
You must include the library <b>lib/luaj-jme-3.0-alpha1.jar</b> in your midlet jar.
|
||||
You must include the library <b>lib/luaj-jme-3.0-alpha2.jar</b> in your midlet jar.
|
||||
|
||||
<p>
|
||||
An ant script to build and run the midlet is in
|
||||
@@ -311,7 +311,7 @@ The standard use of JSR-223 scripting engines may be used:
|
||||
All standard aspects of script engines including compiled statements should be supported.
|
||||
|
||||
<p>
|
||||
You must include the library <b>lib/luaj-jse-3.0-alpha1.jar</b> in your class path.
|
||||
You must include the library <b>lib/luaj-jse-3.0-alpha2.jar</b> in your class path.
|
||||
|
||||
<p>
|
||||
A working example may be found in
|
||||
@@ -323,7 +323,7 @@ To compile and run it using Java 1.6 or higher:
|
||||
|
||||
<pre>
|
||||
javac examples/jse/ScriptEngineSample.java
|
||||
java -cp "lib/luaj-jse-3.0-alpha1.jar;examples/jse" ScriptEngineSample
|
||||
java -cp "lib/luaj-jse-3.0-alpha2.jar;examples/jse" ScriptEngineSample
|
||||
</pre>
|
||||
|
||||
<h2>Excluding the lua bytecode compiler</h2>
|
||||
@@ -487,7 +487,7 @@ The following lua script will open a swing frame on Java SE:
|
||||
See a longer sample in <em>examples/lua/swingapp.lua</em> for details, including a simple animation loop, rendering graphics, mouse and key handling, and image loading.
|
||||
Or try running it using:
|
||||
<pre>
|
||||
java -cp lib/luaj-jse-3.0-alpha1.jar lua examples/lua/swingapp.lua
|
||||
java -cp lib/luaj-jse-3.0-alpha2.jar lua examples/lua/swingapp.lua
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -574,11 +574,11 @@ Each of these functions has an abstract method that must be implemented,
|
||||
and argument fixup is done automatically by the classes as each Java function is invoked.
|
||||
|
||||
<p>
|
||||
For example, to implement a "hello, world" function, we could supply:
|
||||
An example of a function with no arguments but a useful return value might be:
|
||||
<pre>
|
||||
pubic class hello extends ZeroArgFunction {
|
||||
pubic class hostname extends ZeroArgFunction {
|
||||
public LuaValue call() {
|
||||
env.get("print").call(valueOf("hello, world"));
|
||||
return valueOf(java.net.InetAddress.getLocalHost().getHostName());
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
@@ -589,20 +589,90 @@ by the instantiating object whenever default loading is used.
|
||||
<p>
|
||||
Calling this function from lua could be done by:
|
||||
<pre>
|
||||
require( 'hello' )()
|
||||
local hostname = require( 'hostname' )
|
||||
</pre>
|
||||
|
||||
while calling this function from Java would look like:
|
||||
<pre>
|
||||
new hello().call();
|
||||
new hostname().call();
|
||||
</pre>
|
||||
|
||||
Note that in both the lua and Java case, extra arguments will be ignored, and the function will be called.
|
||||
Also, no virtual machine instance is necessary to call the function.
|
||||
To allow for arguments, or return multiple values, extend one of the other base classes.
|
||||
|
||||
<h2>Libraries of Java Functions</h2>
|
||||
When require() is called, it will first attempt to load the module as a Java class that implements LuaFunction.
|
||||
To succeed, the following requirements must be met:
|
||||
<ul>
|
||||
<li>The class must be on the class path with name, <em>modname</em>.</li>
|
||||
<li>The class must have a public default constructor.</li>
|
||||
<li>The class must inherit from LuaFunction.</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
If luaj can find a class that meets these critera, it will instantiate it, cast it to <em>LuaFunction</em>
|
||||
then call() the instance with two arguments:
|
||||
the <em>modname</em> used in the call to require(), and the environment for that function.
|
||||
The Java may use these values however it wishes. A typical case is to create named functions
|
||||
in the environment that can be called from lua.
|
||||
|
||||
<p>
|
||||
A complete example of Java code for a simple toy library is in <a href="examples/jse/hyperbolic.java">examples/jse/hyperbolic.java</a>
|
||||
<pre>
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.*;
|
||||
|
||||
public class hyperbolic extends TwoArgFunction {
|
||||
|
||||
public hyperbolic() {}
|
||||
|
||||
public LuaValue call(LuaValue modname, LuaValue env) {
|
||||
LuaValue library = tableOf();
|
||||
library.set( "sinh", new sinh() );
|
||||
library.set( "cosh", new cosh() );
|
||||
env.set( "hyperbolic", library );
|
||||
return library;
|
||||
}
|
||||
|
||||
static class sinh extends OneArgFunction {
|
||||
public LuaValue call(LuaValue x) {
|
||||
return LuaValue.valueOf(Math.sinh(x.checkdouble()));
|
||||
}
|
||||
}
|
||||
|
||||
static class cosh extends OneArgFunction {
|
||||
public LuaValue call(LuaValue x) {
|
||||
return LuaValue.valueOf(Math.cosh(x.checkdouble()));
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
In this case the call to require invokes the library itself to initialize it. The library implementation
|
||||
puts entries into a table, and stores this table in the environment.
|
||||
|
||||
<p>
|
||||
The lua script used to load and test it is in <a href="examples/lua/hyperbolicapp.lua">examples/lua/hyperbolicapp.lua</a>
|
||||
<pre>
|
||||
require 'hyperbolic'
|
||||
|
||||
print('hyperbolic', hyperbolic)
|
||||
print('hyperbolic.sinh', hyperbolic.sinh)
|
||||
print('hyperbolic.cosh', hyperbolic.cosh)
|
||||
|
||||
print('sinh(0.5)', hyperbolic.sinh(0.5))
|
||||
print('cosh(0.5)', hyperbolic.cosh(0.5))
|
||||
</pre>
|
||||
|
||||
For this example to work the code in <em>hyperbolic.java</em> must be compiled and put on the class path.
|
||||
|
||||
<h2>Closures</h2>
|
||||
Closures still exist in this framework, but are optional, and are only used to implement lua bytecode execution.
|
||||
Closures still exist in this framework, but are optional, and are only used to implement lua bytecode execution,
|
||||
and is generally not directly manipulated by the user of luaj.
|
||||
<p>
|
||||
See the <a href="http://luaj.sourceforge.net/api/3.0/org/luaj/vm2/LuaClosure.html">org.luaj.vm2.LuaClosure</a>
|
||||
javadoc for details on using that class directly.
|
||||
|
||||
<h1>6 - <a name="6">Parser</a></h1>
|
||||
|
||||
@@ -712,11 +782,13 @@ and LuaForge:
|
||||
<tr valign="top"><td> <b>2.0</b></td><td><ul>
|
||||
<li>Initial release of 2.0 version </li>
|
||||
</ul></td></tr>
|
||||
|
||||
<tr valign="top"><td> <b>2.0.1</b></td><td><ul>
|
||||
<li>Improve correctness of singleton construction related to static initialization </li>
|
||||
<li>Fix nan-related error in constant folding logic that was failing on some JVMs </li>
|
||||
<li>JSR-223 fixes: add META-INF/services entry in jse jar, improve bindings implementation </li>
|
||||
</ul></td></tr>
|
||||
|
||||
<tr valign="top"><td> <b>2.0.2</b></td><td><ul>
|
||||
<li>JSR-223 bindings change: non Java-primitives will now be passed as LuaValue </li>
|
||||
<li>JSR-223 enhancement: allow both ".lua" and "lua" as extensions in getScriptEngine() </li>
|
||||
@@ -725,16 +797,28 @@ and LuaForge:
|
||||
<li>Enhance javadoc, put it <a href="docs/api/index.html">in distribution</a> and <a href="http://luaj.sourceforge.net/api/3.0/index.html">on line</a></li>
|
||||
<li>Major refactor of luajava type coercion logic, improve method selection.</li>
|
||||
<li>Add lib/luaj-sources-2.0.2.jar for easier integration into an IDE such as Netbeans </li>
|
||||
<tr valign="top"><td> <b>3.0-alpha1</b></td><td><ul>
|
||||
|
||||
<tr valign="top"><td> <b>2.0.3</b></td><td><ul>
|
||||
<li>Improve coroutine state logic including let unreferenced coroutines be garbage collected </li>
|
||||
<li>Fix lua command vararg values passed into main script to match what is in global arg table </li>
|
||||
<li>Add arithmetic metatag processing when left hand side is a number and right hand side has metatable </li>
|
||||
<li>Fix load(func) when mutiple string fragments are supplied by calls to func </li>
|
||||
<li>Allow access to public members of private inner classes where possible </li>
|
||||
<li>Add line and column info to org.luaj.vm2.ast parse tree elements generated using LuaParser </li>
|
||||
<li>Turn on error reporting in LuaParser so line numbers ar available in ParseException </li>
|
||||
<li>Improve compatibility of table.remove() </li>
|
||||
<li>Disallow base library setfenv() calls on Java functions </li>
|
||||
|
||||
<tr valign="top"><td> <b>3.0-alpha1</b></td><td><ul>
|
||||
<li>Convert internal and external API's to match lua 5.2.x environment changes </li>
|
||||
<li>Add bit32 library </li>
|
||||
<li>Add explicit Globals object to manage global state, especially to imrpove thread safety </li>
|
||||
<li>Drop support for lua source to java surce (lua2java) in favor of direct java bytecode output (luajc) </li>
|
||||
<li>Remove compatibility functions like table.getn(), table.maxn(), table.foreach(), and math.log10() </li>
|
||||
<li>Add ability to create runnable jar file from lua script with sample build file build-app.xml </li>
|
||||
|
||||
<tr valign="top"><td> <b>3.0-alpha2</b></td><td><ul>
|
||||
<li>Supply environment as second argument to LibFunction when loading via require() </li>
|
||||
|
||||
</ul></td></tr>
|
||||
</table></td></tr></table>
|
||||
|
||||
|
||||
65
examples/jse/hyperbolic.java
Normal file
65
examples/jse/hyperbolic.java
Normal file
@@ -0,0 +1,65 @@
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.OneArgFunction;
|
||||
import org.luaj.vm2.lib.TwoArgFunction;
|
||||
|
||||
/**
|
||||
* Sample library that can be called via luaj's require() implementation.
|
||||
*
|
||||
* This library, when loaded, creates a lua package called "hyperbolic"
|
||||
* which has two functions, "sinh()" and "cosh()".
|
||||
*
|
||||
* Because the class is in the default Java package, it can be called using
|
||||
* lua code such as:
|
||||
*
|
||||
<pre> {@code
|
||||
* require 'hyperbolic'
|
||||
* print('sinh', hyperbolic.sinh)
|
||||
* print('sinh(1.0)', hyperbolic.sinh(1.0))
|
||||
* }</pre>
|
||||
*
|
||||
* When require() loads the code, two things happen: 1) the public constructor
|
||||
* is called to construct a library instance, and 2) the instance is invoked
|
||||
* as a java call with no arguments. This invocation should be used to initialize
|
||||
* the library, and add any values to globals that are desired.
|
||||
*/
|
||||
public class hyperbolic extends TwoArgFunction {
|
||||
|
||||
/** Public constructor. To be loaded via require(), the library class
|
||||
* must have a public constructor.
|
||||
*/
|
||||
public hyperbolic() {}
|
||||
|
||||
/** The implementation of the TwoArgFunction interface.
|
||||
* This will be called once when the library is loaded via require().
|
||||
* @param modname LuaString containing the name used in the call to require().
|
||||
* @param env LuaValue containing the environment for this function.
|
||||
* @return Value that will be returned in the require() call. In this case,
|
||||
* it is the library itself.
|
||||
*/
|
||||
public LuaValue call(LuaValue modname, LuaValue env) {
|
||||
LuaValue library = tableOf();
|
||||
library.set( "sinh", new sinh() );
|
||||
library.set( "cosh", new cosh() );
|
||||
env.set( "hyperbolic", library );
|
||||
return library;
|
||||
}
|
||||
|
||||
/* Each library function is coded as a specific LibFunction based on the
|
||||
* arguments it expects and returns. By using OneArgFunction, rather than
|
||||
* LibFunction directly, the number of arguments supplied will be coerced
|
||||
* to match what the implementation expects. */
|
||||
|
||||
/** Mathematical sinh function provided as a OneArgFunction. */
|
||||
static class sinh extends OneArgFunction {
|
||||
public LuaValue call(LuaValue x) {
|
||||
return LuaValue.valueOf(Math.sinh(x.checkdouble()));
|
||||
}
|
||||
}
|
||||
|
||||
/** Mathematical cosh function provided as a OneArgFunction. */
|
||||
static class cosh extends OneArgFunction {
|
||||
public LuaValue call(LuaValue x) {
|
||||
return LuaValue.valueOf(Math.cosh(x.checkdouble()));
|
||||
}
|
||||
}
|
||||
}
|
||||
19
examples/lua/hyperbolicapp.lua
Normal file
19
examples/lua/hyperbolicapp.lua
Normal file
@@ -0,0 +1,19 @@
|
||||
-- Sample luaj code to try loading and executing the 'hyperbolic' sample library
|
||||
--
|
||||
-- The sample library source is in examples/jse/hyperbolic.java.
|
||||
-- For this sample to work, that source must be compiled, and the class must
|
||||
-- be on the class path.
|
||||
--
|
||||
-- First load the library via require(). This will call the public constructor
|
||||
-- for the class named 'hyperbolic' if it exists, and then initialize the
|
||||
-- library by invoking LuaValue.call('hyperbolic') on that instance
|
||||
require 'hyperbolic'
|
||||
|
||||
-- Test that the table is in the globals, and the functions exist.
|
||||
print('hyperbolic', hyperbolic)
|
||||
print('hyperbolic.sinh', hyperbolic.sinh)
|
||||
print('hyperbolic.cosh', hyperbolic.cosh)
|
||||
|
||||
-- Try exercising the functions.
|
||||
print('sinh(0.5)', hyperbolic.sinh(0.5))
|
||||
print('cosh(0.5)', hyperbolic.cosh(0.5))
|
||||
@@ -57,40 +57,43 @@ import org.luaj.vm2.Varargs;
|
||||
* <p>
|
||||
* For example, the following code will implement a library called "hyperbolic"
|
||||
* with two functions, "sinh", and "cosh":
|
||||
* <pre> {@code
|
||||
<pre> {@code
|
||||
* import org.luaj.vm2.LuaValue;
|
||||
* public class hyperbolic extends org.luaj.vm2.lib.OneArgFunction {
|
||||
* import org.luaj.vm2.lib.*;
|
||||
*
|
||||
* public class hyperbolic extends TwoArgFunction {
|
||||
*
|
||||
* public hyperbolic() {}
|
||||
* public LuaValue call(LuaValue arg) {
|
||||
* switch ( opcode ) {
|
||||
* case 0: {
|
||||
* LuaValue t = tableOf();
|
||||
* this.bind(t, hyperbolic.class, new String[] { "sinh", "cosh" }, 1 );
|
||||
* env.set("hyperbolic", t);
|
||||
* return t;
|
||||
*
|
||||
* public LuaValue call(LuaValue modname, LuaValue env) {
|
||||
* LuaValue library = tableOf();
|
||||
* library.set( "sinh", new sinh() );
|
||||
* library.set( "cosh", new cosh() );
|
||||
* env.set( "hyperbolic", library );
|
||||
* return library;
|
||||
* }
|
||||
* case 1: return valueOf(Math.sinh(arg.todouble()));
|
||||
* case 2: return valueOf(Math.cosh(arg.todouble()));
|
||||
* default: return error("bad opcode: "+opcode);
|
||||
*
|
||||
* static class sinh extends OneArgFunction {
|
||||
* public LuaValue call(LuaValue x) {
|
||||
* return LuaValue.valueOf(Math.sinh(x.checkdouble()));
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* static class cosh extends OneArgFunction {
|
||||
* public LuaValue call(LuaValue x) {
|
||||
* return LuaValue.valueOf(Math.cosh(x.checkdouble()));
|
||||
* }
|
||||
* }</pre>
|
||||
* The default constructor is both to instantiate the library
|
||||
* }
|
||||
*}
|
||||
*}</pre>
|
||||
* The default constructor is used to instantiate the library
|
||||
* in response to {@code require 'hyperbolic'} statement,
|
||||
* provided it is on Javas class path,
|
||||
* and to instantiate copies of the {@code hyperbolic}
|
||||
* class when initializing library instances. .
|
||||
* The instance returned by the default constructor will be invoked
|
||||
* as part of library loading.
|
||||
* In response, it creates two more instances, one for each library function,
|
||||
* in the body of the {@code switch} statement {@code case 0}
|
||||
* via the {@link #bind(LuaValue, Class, String[], int)} utility method.
|
||||
* It also registers the table in the globals via the {@link #env}
|
||||
* local variable, which should be the global environment unless
|
||||
* it has been changed.
|
||||
* {@code case 1} and {@code case 2} will be called when {@code hyperbolic.sinh}
|
||||
* {@code hyperbolic.sinh} and {@code hyperbolic.cosh} are invoked.
|
||||
* provided it is on Java"s class path.
|
||||
* This instance is then invoked with 2 arguments: the name supplied to require(),
|
||||
* and the environment for this function. The library may ignore these, or use
|
||||
* them to leave side effects in the global environment, for example.
|
||||
* In the previous example, two functions are created, 'sinh', and 'cosh', and placed
|
||||
* into a global table called 'hyperbolic' using the supplied 'env' argument.
|
||||
* <p>
|
||||
* To test it, a script such as this can be used:
|
||||
* <pre> {@code
|
||||
@@ -108,14 +111,14 @@ import org.luaj.vm2.Varargs;
|
||||
* <pre> {@code
|
||||
* t table: 3dbbd23f
|
||||
* hyperbolic table: 3dbbd23f
|
||||
* k,v cosh cosh
|
||||
* k,v sinh sinh
|
||||
* k,v cosh function: 3dbbd128
|
||||
* k,v sinh function: 3dbbd242
|
||||
* sinh(.5) 0.5210953
|
||||
* cosh(.5) 1.127626
|
||||
* }</pre>
|
||||
* <p>
|
||||
* See the source code in any of the library functions
|
||||
* such as {@link BaseLib} or {@link TableLib} for specific examples.
|
||||
* such as {@link BaseLib} or {@link TableLib} for other examples.
|
||||
*/
|
||||
abstract public class LibFunction extends LuaFunction {
|
||||
|
||||
|
||||
@@ -148,28 +148,29 @@ public class PackageLib extends OneArgFunction {
|
||||
/**
|
||||
* require (modname)
|
||||
*
|
||||
* Loads the given module. The function starts by looking into the package.loaded table to
|
||||
* determine whether modname is already loaded. If it is, then require returns the value
|
||||
* Loads the given module. The function starts by looking into the package.loaded table
|
||||
* to determine whether modname is already loaded. If it is, then require returns the value
|
||||
* stored at package.loaded[modname]. Otherwise, it tries to find a loader for the module.
|
||||
*
|
||||
* To find a loader, require is guided by the package.loaders array. By changing this array,
|
||||
* we can change how require looks for a module. The following explanation is based on the
|
||||
* default configuration for package.loaders.
|
||||
* To find a loader, require is guided by the package.searchers sequence.
|
||||
* By changing this sequence, we can change how require looks for a module.
|
||||
* The following explanation is based on the default configuration for package.searchers.
|
||||
*
|
||||
* First require queries package.preload[modname]. If it has a value, this value
|
||||
* (which should be a function) is the loader. Otherwise require searches for a Lua loader
|
||||
* using the path stored in package.path. If that also fails, it searches for a C loader
|
||||
* using the path stored in package.cpath. If that also fails, it tries an all-in-one loader
|
||||
* (see package.loaders).
|
||||
* (which should be a function) is the loader. Otherwise require searches for a Lua loader using
|
||||
* the path stored in package.path. If that also fails, it searches for a Java loader using
|
||||
* the classpath, using the public default constructor, and casting the instance to LuaFunction.
|
||||
*
|
||||
* Once a loader is found, require calls the loader with a single argument, modname.
|
||||
* If the loader returns any value, require assigns the returned value to package.loaded[modname].
|
||||
* If the loader returns no value and has not assigned any value to package.loaded[modname],
|
||||
* then require assigns true to this entry. In any case, require returns the final value of
|
||||
* package.loaded[modname].
|
||||
* Once a loader is found, require calls the loader with two arguments: modname and an extra value
|
||||
* dependent on how it got the loader. If the loader came from a file, this extra value is the file name.
|
||||
* If the loader is a Java instance of LuaFunction, this extra value is the environment.
|
||||
* If the loader returns any non-nil value, require assigns the returned value to package.loaded[modname].
|
||||
* If the loader does not return a non-nil value and has not assigned any value to package.loaded[modname],
|
||||
* then require assigns true to this entry.
|
||||
* In any case, require returns the final value of package.loaded[modname].
|
||||
*
|
||||
* If there is any error loading or running the module, or if it cannot find any loader for
|
||||
* the module, then require signals an error.
|
||||
* If there is any error loading or running the module, or if it cannot find any loader for the module,
|
||||
* then require raises an error.
|
||||
*/
|
||||
public class require extends OneArgFunction {
|
||||
public LuaValue call( LuaValue arg ) {
|
||||
@@ -184,24 +185,24 @@ public class PackageLib extends OneArgFunction {
|
||||
/* else must load it; iterate over available loaders */
|
||||
LuaTable tbl = PackageLib.this.searchers.checktable();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
LuaValue chunk = null;
|
||||
Varargs loader = null;
|
||||
for ( int i=1; true; i++ ) {
|
||||
LuaValue loader = tbl.get(i);
|
||||
if ( loader.isnil() ) {
|
||||
LuaValue searcher = tbl.get(i);
|
||||
if ( searcher.isnil() ) {
|
||||
error( "module '"+name+"' not found: "+name+sb );
|
||||
}
|
||||
|
||||
/* call loader with module name as argument */
|
||||
chunk = loader.call(name);
|
||||
if ( chunk.isfunction() )
|
||||
loader = searcher.invoke(name);
|
||||
if ( loader.isfunction(1) )
|
||||
break;
|
||||
if ( chunk.isstring() )
|
||||
sb.append( chunk.tojstring() );
|
||||
if ( loader.isstring(1) )
|
||||
sb.append( loader.tojstring(1) );
|
||||
}
|
||||
|
||||
// load the module using the loader
|
||||
loaded.set(name, _SENTINEL);
|
||||
result = chunk.call(name);
|
||||
result = loader.arg1().call(name, loader.arg(2));
|
||||
if ( ! result.isnil() )
|
||||
loaded.set( name, result );
|
||||
else if ( (result = PackageLib.this.loaded.get(name)) == _SENTINEL )
|
||||
@@ -309,7 +310,7 @@ public class PackageLib extends OneArgFunction {
|
||||
v = (LuaValue) c.newInstance();
|
||||
if (v.isfunction())
|
||||
((LuaFunction)v).initupvalue1(globals);
|
||||
return v;
|
||||
return varargsOf(v, globals);
|
||||
} catch ( ClassNotFoundException cnfe ) {
|
||||
return valueOf("\n\tno class '"+classname+"'" );
|
||||
} catch ( Exception e ) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
version: 3.0-alpha1
|
||||
version: 3.0-alpha2
|
||||
Reference in New Issue
Block a user