https://github.com/kroepke/luna
Lua 5.3 implementation for the JVM
https://github.com/kroepke/luna
jvm-languages lua lua53 scripting
Last synced: 12 months ago
JSON representation
Lua 5.3 implementation for the JVM
- Host: GitHub
- URL: https://github.com/kroepke/luna
- Owner: kroepke
- License: apache-2.0
- Created: 2017-05-31T21:28:39.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2017-07-27T16:07:05.000Z (over 8 years ago)
- Last Synced: 2025-02-04T01:35:10.795Z (about 1 year ago)
- Topics: jvm-languages, lua, lua53, scripting
- Language: Java
- Homepage:
- Size: 3.67 MB
- Stars: 22
- Watchers: 5
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: Changelog.md
- License: LICENSE.txt
Awesome Lists containing this project
README
[](https://travis-ci.org/kroepke/luna)
[](https://javadoc.io/doc/org.classdump.luna/luna-runtime)
[](https://javadoc.io/doc/org.classdump.luna/luna-stdlib)
[](https://javadoc.io/doc/org.classdump.luna/luna-compiler)
# Luna
(*Luna* is Spanish for *Moon*.)
## About
Luna is an implementation of Lua 5.3 for the Java Virtual Machine (JVM), written in
pure Java with minimal dependencies.
The goal of the Luna project is to develop a correct, complete and scalable Lua
implementation for running sandboxed Lua programs on the JVM.
Luna implements Lua 5.3 as specified by the
[Lua Reference Manual](http://www.lua.org/manual/5.3/manual.html), explicitly attempting to mimic
the behaviour of PUC-Lua whenever possible. This includes language-level features (such
as metamethods and coroutines) and the standard library.
## Credits
Luna is a fork of [Rembulan](https://github.com/mjanicek/rembulan) created by Miroslav Janíček.
Sadly his excellent project seems to be abandoned and is also not published on Maven Central.
In order to make Lua 5.3 useful in JVM projects, I decided to fork and publish the project
so that his great work does not get lost.
## Status
The majority of language-level features is implemented, and may be expected
to work. If you find behaviour that does not conform to Lua 5.3 as defined by the Lua Reference
Manual, please [open a new issue](https://github.com/kroepke/luna/issues).
See also the [completeness table](doc/CompletenessTable.md) that maps out the current
completeness status of Luna with regard to PUC-Lua, in particular the standard library.
## Frequently asked questions (FAQ)
#### What is Luna good for?
Lua is a small, beautifully-designed and simple-yet-powerful programming language.
Lua has been traditionally used as an embedded scripting language. Luna aims to serve
a similar purpose on the JVM, with an explicit focus on sandboxing the client Lua programs.
There are two main use-cases for Luna: running untrusted Lua scripts on the JVM,
and enhancing Java applications by adding the ability to script them with Lua.
#### Does Luna implement the Lua C API?
No, at this point Luna requires libraries to be written against its Java interface.
#### Does Luna work with Lua bytecode?
No. The Lua bytecode (i.e., the bytecode generated by PUC-Lua's `luac`) is considered
an implementation detail by both Luna and the Lua Reference Manual. Luna implements
its own compiler and compiles to Java bytecode directly. It uses its own
intermediate representation (IR) annotated with statically-inferred type information,
but does not expose it to the user, and the IR has no serialisable form.
For more information about the Luna compiler, see the [compiler overview](doc/CompilerOverview.md).
#### How are coroutines implemented?
See [How are coroutines implemented?](doc/CoroutinesOverview.md)
## Using Luna
Luna requires a Java Runtime Environment (JRE) version 8 or higher.
### Documentation
Generated JavaDocs are available online:
* [](https://javadoc.io/doc/org.classdump.luna/luna-runtime)
* [](https://javadoc.io/doc/org.classdump.luna/luna-stdlib)
* [](https://javadoc.io/doc/org.classdump.luna/luna-compiler)
There are also a few short texts in the `doc` folder:
* [How are coroutines implemented?](doc/CoroutinesOverview.md)
* [Overview of the Luna compiler](doc/CompilerOverview.md)
* [Luna completeness table](doc/CompletenessTable.md)
### Building from source
To build Luna, you will need the following:
* Java Development Kit (JDK) version 8 or higher
* Maven version 3 or higher
Maven will pull in the remaining dependencies as part of the build process.
To fetch the latest code on the `master` branch and build it, run
```sh
git clone https://github.com/kroepke/luna.git
cd luna
mvn install
```
This will build all modules, run tests and finally install all artifacts into your local
Maven repository.
#### Standalone REPL
Much like PUC-Lua, Luna contains a standalone REPL. This is provided in the module
`luna-standalone`. To build the REPL, run
```sh
mvn package -DskipTests -Dmaven.javadoc.skip=true -DstandaloneFinalName=luna
```
The standalone REPL is packaged as a self-contained, executable [Capsule](http://www.capsule.io)
and is placed in the directory `luna-standalone/target`.
To run the REPL:
```sh
cd luna-standalone/target
./luna-capsule.x
```
The standalone REPL mimics the behaviour or the standalone PUC-Lua interpreter and may be
used as its drop-in replacement.
```
$ ./luna-capsule.x
Luna 0.3-SNAPSHOT (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_60)
> print("hello world!")
hello world!
```
### Using Luna from Maven
[](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.classdump.luna%22)
Release are published to [Maven Central](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.classdump.luna%22).
Typically, if you plan to embed Luna, the safest way of doing so is to use the **luna-all-shaded** module. It renames
the ASM library, which is often required by other projects in incompatible versions, leading to problems.
This module combines **runtime**, **compiler** and **stdlib**, because those are all typically required.
To include the **luna-all-shaded** as a dependency:
```xml
org.classdump.luna
luna-all-shaded
0.2
```
To include the **runtime** as a dependency:
```xml
org.classdump.luna
luna-runtime
0.2
```
To include the **compiler** as a dependency:
```xml
org.classdump.luna
luna-compiler
0.2
```
To include the **standard library** as a dependency:
```xml
org.classdump.luna
luna-stdlib
0.2
```
Note that `luna-compiler` and `luna-stdlib` both pull in `luna-runtime` as
a dependency, but are otherwise independent. (I.e., to use the compiler and the standard
library, you need to declare both `-compiler` and `-stdlib` as dependencies, but do not need
to include `-runtime`).
## Getting started
Luna compiles Lua functions into Java classes and loads them into the JVM;
the compiler performs a type analysis of the Lua programs in order to generate a more
tightly-typed code whenever feasible.
Since the JVM does not directly support coroutines, Luna treats Lua functions as state
machines and controls their execution (i.e., yields, resumes and pauses) using exceptions.
Since the Luna runtime retains control of the control state, this technique is also used
to implement CPU accounting and scheduling of asynchronous operations.
#### Example: Hello world
The following snippet loads the Lua program `print('hello world!')`, compiles it, loads
it into a (non-sandboxed) state, and runs it:
(From [`luna-examples/.../HelloWorld.java`](luna-examples/src/main/java/org/classdump/luna/examples/HelloWorld.java))
```java
public class Main {
public static void main(String[] args) {
String program = "print('hello world!')";
// initialise state
StateContext state = StateContexts.newDefaultInstance();
Table env = StandardLibrary.in(RuntimeEnvironments.system()).installInto(state);
// compile
ChunkLoader loader = CompilerChunkLoader.of("hello_world");
LuaFunction main = loader.loadTextChunk(new Variable(env), "hello", program);
// execute
DirectCallExecutor.newExecutor().call(state, main);
}
}
```
The output (printed to `System.out`) is:
```
hello world!
```
#### Example: CPU accounting
Lua functions can be called in a mode that automatically pauses their execution once the
given number of operations has been performed:
(From [`luna-examples/.../InfiniteLoop.java`](luna-examples/src/main/java/org/classdump/luna/examples/InfiniteLoop.java))
```java
public class Main {
public static void main(String[] args) {
String program = "n = 0; while true do n = n + 1 end";
// initialise state
StateContext state = StateContexts.newDefaultInstance();
Table env = StandardLibrary.in(RuntimeEnvironments.system()).installInto(state);
// compile
ChunkLoader loader = CompilerChunkLoader.of("infinite_loop");
LuaFunction main = loader.loadTextChunk(new Variable(env), "loop", program);
// execute at most one million ops
DirectCallExecutor executor = DirectCallExecutor.newExecutorWithTickLimit(1000000);
try {
executor.call(state, main);
throw new AssertionError(); // never reaches this point!
}
catch (CallPausedException ex) {
System.out.println("n = " + env.rawget("n"));
}
}
}
```
Prints:
```
n = 199999
```
The [`CallPausedException`](https://static.javadoc.io/org.classdump.luna/luna-runtime/0.2/org/classdump/luna/exec/Continuation.html) contains a *continuation* of the call. The call can be resumed:
the pause is transparent to the Lua code, and the loop does not end with an error (it is merely
paused).
#### Further examples
For further examples, see the classes in
[`luna-examples/src/main/java/org/classdump/luna/examples`](luna-examples/src/main/java/org/classdump/luna/examples).
### Project structure
Luna is a multi-module Maven build, consisting of the following modules that are deployed
to Sonatype OSSRH:
* `luna-runtime` ... the core classes and runtime;
* `luna-compiler` ... a compiler of Lua sources to Java bytecode;
* `luna-stdlib` ... the Lua standard library;
* `luna-standalone` ... standalone REPL, a (mostly) drop-in replacement
for the `lua` command from PUC-Lua.
There are also auxiliary modules that are not deployed:
* `luna-tests` ... project test suite, including benchmarks from
the Benchmarks Game;
* `luna-examples` ... examples of the Luna API.
## Contributing
Contributions of all kinds are welcome!
## License
Luna is licensed under the Apache License Version 2.0. See the file
[LICENSE.txt](LICENSE.txt) for details.