My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
KahluaManual  
Kahlua Manual
Featured
Updated Jun 11, 2009 by kristofer.karlsson@gmail.com

Contents

Building Kahlua

Kahlua uses Apache Ant to build itself. Simply run ant from the project root to compile, package and run all the test cases.

Testing

Kahlua is developed by Test Driven Development and uses its own test suite (implemented in Lua) to verify that it's always working correctly. It currently has about 98% code coverage.

After having built Kahlua, you can find a test report inside testreport.html and a coverage report inside testsuite/coverage/coverage.html.

Differences compared with regular Lua

Kahlua is not fully compatible with Lua, which is to be expected as it only runs from Java CLDC 1.1.

Some functions in the standard library are missing and some functions do not behave exactly the same way. This is all documented in order to help the transition from Lua to Kahlua.

Basic Kahlua types

The fundamental types in Lua of course have their corresponding type in Kahlua. nil, number, boolean and string map directly to null, Double, Boolean and String. table and coroutine map to Kahlua's own LuaTable and LuaThread. function maps to either the JavaFunction interface if it's implemented in Java and LuaClosure if it's a Lua function.

This means that you can pass doubles, booleans and strings directly into Lua without any problems.

Garbage collection

Kahlua uses Javas own garbage collection with means that all of the collectgarbage options are not supported, as well as the __gc metatable mode.

Userdata

Kahlua does not share Luas concept of userdata. Instead, you can simply pass any object into Kahlua. In order to operate on them, you must set the metatable for the class, which will then apply to all objects of exactly that class (not subclasses).

The only way to operate on userdata is to export java functions that can manipulate them. (See example of this in the UserdataArray class.)

Strings

Strings in Kahlua are represented in UTF-16, just like Java strings (this is because Kahlua strings are in fact represented as Java strings).

Missing functions

The following functions are not implemented in Kahlua:

  • io.*
  • debug.*
  • string.dump (but you can dump a closure into an InputStream from Java)
  • loadstring, loadfile, load, dofile (but loadstring is available if you link with LuaJ)
  • gcinfo
  • xpcall
  • os.execute, os.exit, os.setlocale, os.getenv, os.remove, os.clock, os.tmpname, os.rename
  • newproxy
  • gcinfo (deprecated in lua)

Functions with different behaviour

These functions behave almost like in Lua:

pcall

pcall only differs in the return values on failure. pcall in Lua returns false, errormessage pcall in Kahlua returns:

  1. false
  2. errormessage
  3. stacktrace (as a string with newlines separating each call frame)
  4. the original java exception

collectgarbage

collectgarbage([opt]) works like this for the following values of opt:

  • null, "step", "collect" all run System.gc() in Java, which doesn't guarantee any specific behaviour in Java
  • "count" returns three values: usedMemory, freeMemory, totalMemory (all in KB)
  • all other values for opt result in an error.

error

Instead of being error(message, [level]) as in Lua, Kahlua has error(message, [stacktrace]). stacktrace is appended to the total stacktrace when caught by pcall.

Just like in Lua, if error is called with zero parameters, it does nothing.

Functions that behave the same as in Lua

  • assert
  • getfenv, setfenv
  • getmetatable, setmetatable
  • next, ipairs, pairs
  • rawequal, rawget, rawset
  • select
  • tonumber, tostring
  • type
  • unpack
  • module
  • require
  • coroutine.*
  • string.*
  • table.*
  • math.*
  • os.date, os.difftime, os.time

Extra functions

debugstacktrace

There is already a similar function in Lua, called debug.traceback ([thread,] [message] [, level]).

debugstacktrace in Kahlua is used like this: debugstacktrace(thread, level, count, halt_at).

  • thread is the thread to inspect. A value of nil represents the current thread.
  • level is an integer >= 0 representing at which stack level to start. level 0 is debugstacktrace itself, level 1 is the function that called debugstacktrace, and so on. The default value is 0.
  • count is an integer representing the upper limit of how many stackframes to return. Defaults to all stackframes
  • halt_at is an integer representing the stack height at which to stop giving a stacktrace. The default value is 0.

Compat options

Kahlua implements no compat-options, i.e. no support for arg as in Lua 5.0

Compiler

Kahlua currently does not have its own compiler, but it has support for using LuaJs compiler. This is very easy to do, just add LuaJ to the classpath, and run

LuaCompiler.register(state)

You will then get access to loadstring inside Lua. Also take a look at the source code inside testsuite/src for examples on how to use it.

Kahlua can also natively load precompiled Lua 5.1b bytecode. Use luac -o output.lbc input.lua to compile a lua source file to bytecode. You can then use LuaPrototype.loadBytecode to get a lua closure.

Thread safety

Kahlua is not thread safe in any way. Do not attempt to use a LuaState concurrently from different threads. Also do not try to move a LuaFunction or JavaFunction into a different state. Sharing of booleans, numbers, strings and tables is safe, but you must manually ensure that no thread is writing to a LuaTable while another is reading (or writing), since the data structure is not thread safe.

However, you can create as many LuaStates as you want to run in different threads if they do not communicate directly. All LuaStates are completely independent of one another and do not share any writeable static fields.

Java API

It's quite easy to add Kahlua to your Java application. For a quick start guide, I recommend looking at Test.java and the midlet demo distributed with Kahlua. They are both quite simple classes. The midlet even shows how to export its own function to Kahlua.

Exporting your own functions to Lua

Kahlua defines an interface called JavaFunction, which needs only one method:

int call(LuaCallFrame callFrame, int nArguments);

callFrame contains all the input arguments, which can be reached by using callFrame.get(i), where 0 <= i < nArguments

Note that nArguments is how many arguments it was called with, not how many you expect. You should be prepared to handle both when you receive fewer or more arguments than expected. Also note that all numbers from Lua will be in the type Double, so if you're expecting an int or a long, you have to do the conversion yourself.

It's safe to throw any kind of RuntimeException from here - Lua will catch it and convert it to a proper Lua error.

Input is only half of the fun though, you may also want to send some output back. The outputs are placed at the same place as the inputs, so you can either choose to overwrite them directly, or push the return values above them. Kahlua will take care of removing the unwanted objects after the return.

Use callFrame.push(object) to push as many objects that you want to return. Then, return that same number.

You can also use callFrame.setTop(nReturnValues) to specify how many return values you want, and then use callFrame.set(index, object) to fill up the list of return values. As with the input, 0 <= index < nReturnValues.

In either case, ALWAYS remember to return the number of return values, which must be an integer >= 0. For examples on how JavaFunctions typically look, see any of the classes in se.krka.kahlua.stdlib

Inspecting Lua from Java

Unlike Lua, Kahlua does not need a large set of API functions to be useful. While Lua provides a clear distinction between Lua space and C space, Kahlua does not do the same for Java. Lua objects are not directly available to C code, so instead you must manipulate them by using the API helper functions. For instance, to get a value out of a table in Lua, you must do something like:

lua_State *L = myState;
lua_getglobal(L, "myTable");
lua_pushstring(L, "myKey");
lua_gettable(L, stack_index);
lua_gettable(L, -2);
// the value is now at stack index -1, to inspect it, use
if (lua_isboolean(L, -1)) {
   bool value = lua_toboolean(L, -1);
}

In Kahlua, you don't need such helper functions, you can use the Java objects directly:

LuaState state = myState;
LuaTable table = (LuaTable) state.getEnvironment().rawget("myTable");
Object value = table.rawget("myKey");
if (value instanceof Boolean) {
	boolean value = ((Boolean) value).booleanValue();
}

The only helper functions you really need are LuaState.getEnvironment() and LuaState.pcall().

Comment by zhon...@gmail.com, Aug 19, 2010

Dear Sir., How can I extract a lua function from a lua script file and invoke it with Kalua? In fact,if I have a lua chunk like this:

print("Hello, lua function call with kahlua.")

function f1(a,b)
  return a+b
end

print(f1(3,5))

,and I load it with "loadis(InputStream?, String, LuaState?)", how can I get kahlua invoke this lua function "f1(a,b)"?

Comment by kiranku...@gmail.com, Nov 8, 2010

A small note - No where in the documentation it is mentioned which version of Lua compiler is required. The example MIDlet shipped works fine if you use Lua 5.1 compiler. It doesn't work with 5.2.


Sign in to add a comment
Powered by Google Project Hosting